클래스의 함수 선언 후 "default"는 무엇을 의미합니까?


221

default클래스의 함수 선언 옆에 사용 된 것을 보았습니다 . 무엇을합니까?

class C {
  C(const C&) = default;
  C(C&&) = default;
  C& operator=(const C&) & = default;
  C& operator=(C&&) & = default;
  virtual ~C() { }
};

26
대입 연산자 선언에서 "="앞에있는 "&"는 무엇을합니까?
dshin

답변:


249

그것은의 새로운 C ++ 11 기능 .

즉, 컴파일러에서 생성 한 해당 함수 버전을 사용하려고하므로 본문을 지정할 필요가 없습니다.

컴파일러가 해당 함수를 자동으로 생성 하지 않도록= delete 지정할 수도 있습니다 .

이동 생성자 및 이동 할당 연산자가 도입되면서 생성자, 소멸자 및 할당 연산자의 자동 버전이 생성되는 규칙이 상당히 복잡해졌습니다. 규칙을 기억할 필요가 없으므로 사용 = default하고 = delete일을 더 쉽게 만듭니다. 원하는 것을 말하면됩니다.


17
= delete더 강함 : 과부하 해결에 여전히 참여하지만 해당 기능의 사용이 금지됨을 의미합니다.
중복 제거기

2
그러나 컴파일러 생성 정의를 사용하려면 "먼저 작성하고 기본값으로 지정"하는 대신 해당 함수 작성을 건너 뛰어서는 안됩니까?
Mayank Jindal

47

이것은 컴파일러에게 각 생성자 또는 할당 연산자의 기본 버전, 즉 각 멤버에 대한 복사 또는 이동 작업을 수행하는 기본 버전을 작성하도록 지시하는 새로운 C ++ 0x 기능입니다. 이것은 복사 생성자와는 달리 이동 생성자가 항상 기본적으로 생성되지는 않기 때문에 유용합니다 (예 : 사용자 정의 소멸자가있는 경우). 컴파일러는 매번 철자를 쓰는 것보다 처리합니다.

또한 기본이 아닌 다른 생성자를 제공하면 기본 생성자가 생성되지 않습니다. 여전히 기본 생성자를 원한다면이 구문을 사용하여 컴파일러에서 생성자를 만들 수 있습니다.

또 다른 사용 사례로, 복사 생성자가 암시 적으로 생성되지 않는 몇 가지 상황이 있습니다 (예 : 사용자 정의 이동 생성자를 제공하는 경우). 여전히 기본 버전을 원하면이 구문으로 요청할 수 있습니다.

자세한 내용은 표준 12.8 절을 참조하십시오.


5
생성자 및 할당뿐만 아니라 operator new/new[], operator delete/delete[]및 해당 오버로드 에도 적용됩니다 .
Sebastian Mach

21

C ++ 11의 새로운 기능입니다 ( 여기 참조) . 하나의 생성자를 정의했지만 다른 생성자를 위해 기본값을 사용하려는 경우 매우 유용 할 수 있습니다. C ++ 11 이전에는 모든 생성자가 기본값과 동일하더라도 정의한 후에는 모든 생성자를 정의해야합니다.

또한 어떤 상황에서는 컴파일러가 기본 초기화 모두에서 합성 한 것과 동일하게 동작하는 사용자 정의 기본 생성자를 제공 할 수 없습니다. default그 행동을 되 찾을 수 있습니다.


5
두 번째 단락과 관련하여 예를 들어 줄 수 있습니까?
John Smith

11

이 답변에서 언급하지 않은 또 다른 사용 사례는 생성자의 가시성을 쉽게 변경할 수 있다는 것입니다. 예를 들어, 친구 클래스가 복사 생성자에 액세스 할 수 있지만 공개적으로 사용하기를 원하지 않을 수 있습니다.


1

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

— 최종 예]

그렇다면 어떤 함수가 암시 적으로 선언 될 수 있고 언제 일어날 수 있는지에 대한 질문입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.