using
c++11에서 typedef를 대신해서 사용할 수 있는 문법으로 using을 추가한 것이 결론이다.
using을 typedef에 대신해서 사용하는 이유를 알아보자.
typedef int id;
using id2 = int;
// 1) 직관성
// 함수 포인터
typedef void(*MyFunc)();
using MyFunc = void(*)();
// 2) 템플릿
template<typename T>
typedef vector<T> vec; // 에러 템플릿이랑 같이 사용 불가
template<typename T>
using Vector = vector<T>; // 템플릿 지원
enum class
scoped enum이라고도 불린다.
enum class는 이름 공간을 관리할 수 있다는 장점이 있다.
enum PlayerType
{
Knight,
Archer,
Mage,
};
기존에 사용하던 enum은 이 이름이 전역적으로 사용된다. 즉, Knight라는 이름을 PlayerType 이외에 사용할 수 없게 되는 문제가 있었다. 그래서 그전까지는 PT_Knight 등으로 이름 공간을 특별히 관리를 했다.
하지만 enum class는 이름 공간이 { } 안에서만 유효하기 때문에 중복이 되는 모습이다. 만약 몬스터도 기사 타입이 있다고 해보자.
enum PlayerType
{
Knight,
Archer,
Mage,
};
enum class MonsterType
{
Knight,
Archer,
Mage,
};
이럴 경우 중복이 허용되어 빌드가 잘 된다.
다만 암묵적인 변환이 안되기 때문에 static_cast<T> 등을 사용해 캐스팅을 계속 해줘야 한다.
delete
우리가 알던 동적할당의 delete를 얘기하는 것이 아닌 함수를 삭제하는 문법의 delete이다.
우리가 특정 함수를 사용하지 못하게 막고 싶을 때 사용한다. 만약 Knight 클래스가 있다고 하고 그 클래스에서 사용하면 안되는 함수가 있다고 했을 때, 다음과 같이 해 막을 수 있다.
class Knight
{
public:
void GetHp() = delete;
public:
int _hp = 100;
};
만약 어딘가 GetHp를 호출하게되면 삭제된 함수라고 뜨는 동시에 빌드 에러가 날 것이다.
override, final
가상함수와 연관이 되어있는 키워드이다.
class Player
{
public:
void Attack()
{
cout << "Player !" << endl;
}
};
class Knight : public Player
{
public:
void Attack()
{
cout << "Knight !" << endl;
}
};
이런 상황이라고 해보자. 우리가 선언한 원본이 Knight냐 Player냐에 따라 호출되는 Attack이 다르다. 그래서 그것을 해결하기 위해 virtual 키워드를 사용해 재 정의를 했다.
그런데 모든 Attack에 virtual 키워드를 선언하게 되면 Player가 최초로 사용된 Attack인지 Knight가 최초로 사용된 Attack인지 구별하기 쉽지 않다.
class Player
{
public:
virtual void Attack()
{
cout << "Player !" << endl;
}
};
class Knight : public Player
{
public:
virtual void Attack() override
{
cout << "Knight !" << endl;
}
};
따라서 다음과 같이 사용하면 Player가 원본 Attack임을 한눈에 알 수 있고 (가독성 증가) 또한, 만약 Knight가 원본이라면 override 문법이 통과되지 않을 것이다.
final 키워드는 내 자식 class에서 더이상 가상함수를 사용하지 않겠다는 의미이다.
class Player
{
public:
virtual void Attack()
{
cout << "Player !" << endl;
}
};
class Knight : public Player
{
public:
virtual void Attack() final
{
cout << "Knight !" << endl;
}
};
'C++ > 기초' 카테고리의 다른 글
[Modern C++] 람다(lambda), 스마트 포인터 (1) | 2023.12.06 |
---|---|
[Modern C++] 오른값 참조(rvalue reference), 전달 참조(forwarding reference) (1) | 2023.12.06 |
[Modern C++] auto, 중괄호 초기화, nullptr (1) | 2023.12.05 |
[C++] STL - deque, map, set, multimap, multiset (1) | 2023.12.05 |
[C++] STL - List (0) | 2023.12.04 |