bdfgdfg
[C++11] default,delete,final,override 키워드 본문
default,delete
C++11에서부터 default키워드를 이용하여 명시적으로 default한 생성자를 선언할 수 있다.
1
2
3
4
5
6
7
|
class Test
{
// 컴파일러가 기본적으로 기본생성자,소멸자,복사생성자등을 만든다.
private:
int m_test;
};
|
cs |
C++11이전부터 클래스 내부의 생성자를 만들지 않더라도 기본적으로 기본생성자,복사생성자,대입복사연산자,소멸자
등을 만들어 줬다. (+ C++11이후에는 기본 생성 함수에 move 생성자와 대입연산자도 추가되었음)
기본 함수를 정의하면 컴파일러는 해당 기본 생성자를 만들어 주지 않는다. default키워드는 그것을 명시적으로 만든다.
그렇기에 비어 있는 생성자나 소멸자를 구체화할 필요가 없으며 기본 생성자 및 소멸자등을 분명하게 표시할 수 있다.
-> 가독성을 위해 명확하게 표현하는것은 좋은 코드 스타일
반대로 컴파일러가 생성자를 만들어주는데 이를 명시적으로 막는(삭제) 방법이 생겼다. 바로 delete 키워드
1
2
3
4
5
6
7
8
9
|
class Test
{
private:
Test(const Test& other) = default;
private:
int m_test;
};
|
cs |
위와 같은 방식으로 Test클래스의 객체를 생성하지 못하도록 막을 수 있다.
다만 생성을 외부에서 못하도록 막을뿐이고 friend를 이용한다면 외부에서도 접근이 가능하다.
즉 의미가 명확하지 않다. 단순히 복사를 금지하는 코드인지, friend를 통해 해당 클래스에서만 접근하게 할것인지.
C++11에서는 명확하게 복사 생성자를 호출하지 못하도록 삭제하는 방법이 존재한다.
1
2
3
4
5
6
7
8
9
|
class Test
{
public:
Test() = default;
Test(const Test& other) = delete;
void operator=(const Test& other) = delete;
private:
int m_test = 100;
};
|
cs |
바로 delete 키워드.
에러 내용을 보면 삭제된 함수라며 호출이 불가능하게끔 되어있다
delete 키워드를 통해 이제 좀 더 명확한 의미전달이 가능하다.
1. 컴파일러가 자동으로 생성자를 만들어 주는것을 원하지 않는다.
2. delete 키워드를 통해 삭제된 함수는 호출되어서는 안된다.
final,override
final키워드는 다른 클래스가 상속을 받지 않게끔 하길 원할 때 사용한다.
이렇게 final키워드가 붙은 클래스를 상속받으면 컴파일 도중에 에러를 잡아준다.
final키워드는 클래스 상속뿐만 아니라, 가상 함수의 오버라이딩을 못하도록 할 때에도 사용된다.
당연하지만 가상 함수가 아니면 쓸 수 없다.(비 가상함수는 final키워드 자체가 적용이 안되서 컴파일 에러를 뱉는다.)
C++11에서는 override 키워드 또한 존재한다.
override는 부모의 가상함수를 자식에서 재정의 하는 것을 의미한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
class Animal
{
public:
virtual void SetAge(int age)
{
}
};
class Dog : public Animal
{
public:
void SetAge(int age)// 재정의(override) 함수인가?
{
}
};
|
cs |
위의 코드의 경우에는 코드라인이 몇줄안되니 금방 재정의된 함수라는 것을 알 수 있지만
보통 C++에서는 클래스마다 헤더/CPP를 나누어 관리를 하므로 이게 부모에서 재정의한 함수인지를 알려면 부모 클래스를 직접 찾아가 확인하는 방법밖에 없다.
-> 심지어 재정의된 함수에 굳이 virtual키워드를 붙이지 않아도 되기에 더욱 헷갈린다.
-> 또한 사용자의 실수로 인해 오버라이딩의 조건인 반환명,함수명,매개변수 타입,개수,const 모두 같지 않다면 오버라이딩이 되지 않는다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
class Animal
{
public:
virtual void GetAge() const
{
}
};
class Dog : public Animal
{
public:
void GetAge() // 재정의된 함수인가?
{
}
};
|
cs |
자식 클래스인 Dog에서 재정의할 멤버함수 GetAge에 const를 붙이지 않았기에 오버라이딩 되지 않는다.
사용자는 이러한 실수를 눈치채지 못하고 넘어갈 수 있다.
이러한 실수를 잡기위해 나온것이 override키워드.
사용자는 부모 클래스의 멤버함수를 재정의하면서 override키워드를 붙여주면 컴파일 타임에 실수여부를 잡을 수 있다.
-> 이제 잘못된 가상 함수 오버라이딩을 막으려면 override키워드를 사용한다.
-> 당연히 가상 함수가 아니라면 쓸 수 없다.
'게임프로그래밍 > C++' 카테고리의 다른 글
[C++ 11] 람다(lambda) 식 (0) | 2022.01.24 |
---|---|
[C++11] using, enum class (1) | 2022.01.22 |
[C++ 11] auto,nullptr (0) | 2022.01.19 |
[C++] C++의 4가지 캐스팅(형변환) (0) | 2022.01.17 |
[C++] 템플릿 (0) | 2022.01.16 |