* default 키워드
C++11에서부터는 default 키워드를 이용하여 명시적으로 default 생성자를 선언할 수 있습니다.
C++11 이전부터 C++ 클래스는 내부를 작성하지 않아도
기본적으로 기본생성자, 복사생성자, 대입연산자, 소멸자 네 가지 멤버함수를 생성합니다.
**C++11부터는 기본 함수에 move 생성자와 move 대입 연산자가 추가되었습니다.
모두가 알다시피, 위의 기본 함수들 중 생성자와 소멸자에 대해서는 중요한 규칙이 있습니다.
어떤 종류의 생성자건, 정의된 생성자가 존재한다면, 컴파일러가 기본 생성자를 만들어주지 않는다는 것입니다.
위와 같은 경우에 default 키워드를 사용하여 명시적으로 생성자를 만들 것을 요구할 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 | //아래의 클래스는 복사 생성자를 private에 선언했습니다. //이 경우 다른 기본 클래스는 생성되지 않기에 아래의 main 문은 컴파일 에러를 발생시키게 됩니다. class MyClass { private : MyClass( const MyClass&); }; int main() { MyClass nc; } |
위의 경우를 해결하기 위해서는 따로 기본 클래스를 public에 선언 및 정의해주어야 합니다.
이를 더 간단화시키고 명시적으로 보이기 위해서 사용하는 것이 default 키워드입니다.
default 키워드를 사용하면 기본 생성자 또는 복사 생성자의 기본 값을 정의할 필요없이
손쉽게 default 생성자를 만들 수 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | //default 키워드를 사용하여 명시적으로 기본 생성자를 생성했습니다 //물론 이 뿐만 아니라 명시적으로 복사생성자 또는 대입 연산자도 생성할 수 있습니다. //이 경우 말 그대로 default한 정의를 하기 때문에 깊은 복사는 이루어지지 않습니다. class MyClass { public : MyClass() = default ; // 위의 경우 MyClass(){}와 같습니다 private : MyClass( const MyClass& class ) = default ; // 따로 복사생성자의 내부를 정의할 필요가 없습니다. }; int main() { MyClass nc; } |
* delete 키워드
delete 키워드도 이와 유사한 방법으로 사용할 수 있습니다.
대표적으로 복사 및 대입이 불가능한 클래스를 만들고 싶을 때를 예로 들 수 있습니다.
이전까지는 private:에 복사 생성자 및 대입 연산자를 선언하고 정의하지 않는 방식을 이용하여
외부에서 접근하는 경우 접근 에러, 실수로 public:에 선언한 경우 링크 에러를 유발하는 방식을 사용했다면,
C++11부터는 delete 키워드를 사용하여 명시적으로 특정 함수에 대한 정의를 금지할 수 있습니다.
아래의 예시 코드를 살펴봅시다
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class MyClass { public : MyClass() {} ~MyClass() {} // 아래의 생성자 및 연산자가 생성되지 않도록 명시합니다. // private에 선언하는 방식보다 더 의도가 명확해집니다. MyClass( const MyClass& class ) = delete ; MyClass& operator = ( const MyClass& class ) = delete ; private : // 아래의 방식이 기존에 사용되던 방식입니다. // private에 선언하여 외부에서의 접근을 막고 // 정의부를 제외하여 실수로 public에 위치시키는 경우에도 링크 에러를 유발합니다. // MyClass(const MyClass& class); // MyClass& operator = (const MyClass& class); }; |
delete는 생성자나 연산자 뿐만 아니라 일반 멤버 함수에도 사용할 수 있기에
이를 응용하여 암시적 형변환이 일어나는 것을 막을 수도 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class NoInteger { // 아래와 같이 함수를 작성하는 경우 매개변수를 int로 암시적 형변환하여 실행하는 것을 막게됩니다. // 따라서 foo(13)을 실행하는 경우 에러가 발생합니다. void foo( double dparam); void foo( int iparam) = delete ; }; struct OnlyDouble { // 아래의 경우는 double외에는 모든 타입에 대해서 막게됩니다. void foo( double d); template < typename T> void foo(T) = delete ; }; |
'프로그래밍(Programming) > c++, 11, 14 , 17, 20' 카테고리의 다른 글
using 과 typedef , typedef 보다는 using (0) | 2016.07.04 |
---|---|
[C++] final 키워드( 선언시, 상속제어 등 ) sealed 한정자 (1) | 2016.07.04 |
리눅스 커널모드 (0) | 2016.06.24 |
클로져 (Closure) 객체 와 람다(lambda) 함수 (0) | 2016.06.03 |
[용어] 하드 코딩 (Hard - coding) (0) | 2016.04.28 |