default
클래스의 함수 선언 옆에 사용 된 것을 보았습니다 . 무엇을합니까?
class C {
C(const C&) = default;
C(C&&) = default;
C& operator=(const C&) & = default;
C& operator=(C&&) & = default;
virtual ~C() { }
};
default
클래스의 함수 선언 옆에 사용 된 것을 보았습니다 . 무엇을합니까?
class C {
C(const C&) = default;
C(C&&) = default;
C& operator=(const C&) & = default;
C& operator=(C&&) & = default;
virtual ~C() { }
};
답변:
그것은의 새로운 C ++ 11 기능 .
즉, 컴파일러에서 생성 한 해당 함수 버전을 사용하려고하므로 본문을 지정할 필요가 없습니다.
컴파일러가 해당 함수를 자동으로 생성 하지 않도록= delete
지정할 수도 있습니다 .
이동 생성자 및 이동 할당 연산자가 도입되면서 생성자, 소멸자 및 할당 연산자의 자동 버전이 생성되는 규칙이 상당히 복잡해졌습니다. 규칙을 기억할 필요가 없으므로 사용 = default
하고 = delete
일을 더 쉽게 만듭니다. 원하는 것을 말하면됩니다.
= delete
더 강함 : 과부하 해결에 여전히 참여하지만 해당 기능의 사용이 금지됨을 의미합니다.
이것은 컴파일러에게 각 생성자 또는 할당 연산자의 기본 버전, 즉 각 멤버에 대한 복사 또는 이동 작업을 수행하는 기본 버전을 작성하도록 지시하는 새로운 C ++ 0x 기능입니다. 이것은 복사 생성자와는 달리 이동 생성자가 항상 기본적으로 생성되지는 않기 때문에 유용합니다 (예 : 사용자 정의 소멸자가있는 경우). 컴파일러는 매번 철자를 쓰는 것보다 처리합니다.
또한 기본이 아닌 다른 생성자를 제공하면 기본 생성자가 생성되지 않습니다. 여전히 기본 생성자를 원한다면이 구문을 사용하여 컴파일러에서 생성자를 만들 수 있습니다.
또 다른 사용 사례로, 복사 생성자가 암시 적으로 생성되지 않는 몇 가지 상황이 있습니다 (예 : 사용자 정의 이동 생성자를 제공하는 경우). 여전히 기본 버전을 원하면이 구문으로 요청할 수 있습니다.
자세한 내용은 표준 12.8 절을 참조하십시오.
operator new/new[]
, operator delete/delete[]
및 해당 오버로드 에도 적용됩니다 .
C ++ 11의 새로운 기능입니다 ( 여기 참조) . 하나의 생성자를 정의했지만 다른 생성자를 위해 기본값을 사용하려는 경우 매우 유용 할 수 있습니다. C ++ 11 이전에는 모든 생성자가 기본값과 동일하더라도 정의한 후에는 모든 생성자를 정의해야합니다.
또한 어떤 상황에서는 컴파일러가 기본 및 값 초기화 모두에서 합성 한 것과 동일하게 동작하는 사용자 정의 기본 생성자를 제공 할 수 없습니다. default
그 행동을 되 찾을 수 있습니다.
C ++ 17 N4659 표준 초안
https://github.com/cplusplus/draft/blob/master/papers/n4659.pdf 11.4.2 "명시 적으로 기본 기능":
1 양식의 함수 정의 :
attribute-specifier-seq opt decl-specifier-seq opt declarator virt-specifier-seq opt = default ;
명시 적 기본 정의라고합니다. 명시 적으로 기본 설정된 기능은
(1.1) — 특별 회원 기능
(1.2) — 선언 된 함수 유형이 동일 함 (참조 한정자가 다를 수 있으며 복사 생성자 또는 복사 할당 연산자의 경우를 제외하고 매개 변수 유형은 "비 상수 T에 대한 참조"일 수 있음) 묵시적으로 선언 된 것처럼 멤버 함수의 클래스 이름)
(1.3) — 기본 인수가 없습니다.
2 삭제 된 것으로 정의되지 않은 명시 적으로 디폴트 된 함수는 constexpr로 내재적으로 선언 된 경우에만 constexpr로 선언 될 수 있습니다. 함수가 첫 번째 선언에서 명시 적으로 기본값을 설정 한 경우 암시 적 선언은 암묵적으로 constexpr로 간주됩니다.
3 명시 적으로 기본 설정된 함수가 암시 적 선언 (18.4)과 동일한 예외 사양을 생성하지 않는 noexcept-specifier로 선언 된 경우
(3.1) — 함수가 첫 번째 선언에서 명시 적으로 기본 설정되어 있으면 삭제 된 것으로 정의됩니다.
(3.2) — 그렇지 않으면 프로그램이 잘못 형성됩니다.
4 [예 :
struct S { constexpr S() = default; // ill-formed: implicit S() is not constexpr S(int a = 0) = default; // ill-formed: default argument void operator=(const S&) = default; // ill-formed: non-matching return type ~ S() noexcept(false) = default; // deleted: exception specification does not match private: int i; // OK: private copy constructor S(S&); }; S::S(S&) = default; // OK: defines copy constructor
— 최종 예]
5 명시 적으로 디폴트 된 함수와 내재적으로 선언 된 함수를 통칭하여 디폴트 함수라고하며, 구현은 그것들에 대한 암시 적 정의를 제공해야합니다 (15.1 15.4, 15.8). 함수는 사용자가 선언하고 첫 번째 선언에서 명시 적으로 기본값을 지정하거나 삭제하지 않으면 사용자가 제공합니다. 사용자가 제공 한 명시 적 기본값 기능 (즉, 첫 번째 선언 후 명시 적으로 기본값이 지정됨)은 명시 적으로 기본값이 지정된 지점에서 정의됩니다. 이러한 기능이 암시 적으로 삭제 된 것으로 정의되면 프로그램이 잘못 구성됩니다. [참고 : 첫 번째 선언 후 함수를 기본값으로 선언하면 효율적인 코드 실행과 간결한 정의를 제공하면서 진화하는 코드 기반에 안정적인 이진 인터페이스를 사용할 수 있습니다. — 끝 참고]
6 [예 :
struct trivial { trivial() = default; trivial(const trivial&) = default; trivial(trivial&&) = default; trivial& operator=(const trivial&) = default; trivial& operator=(trivial&&) = default; ~ trivial() = default; }; struct nontrivial1 { nontrivial1(); }; nontrivial1::nontrivial1() = default; // not first declaration
— 최종 예]
그렇다면 어떤 함수가 암시 적으로 선언 될 수 있고 언제 일어날 수 있는지에 대한 질문입니다.