기본 / 복사 / 이동 ctor 및 복사 / 이동 할당 연산자 자동 생성 조건?


127

컴파일러가 일반적으로 기본 생성자, 복사 생성자 및 할당 연산자를 자동 생성하는 조건에서 메모리를 새로 고치고 싶습니다.

몇 가지 규칙이 있었지만 기억이 나지 않으며 온라인에서 평판이 좋은 자료를 찾을 수 없습니다. 누구든지 도울 수 있습니까?

답변:


136

다음에서 "자동 생성"은 "암시 적으로 기본값으로 선언되었지만 삭제 된 것으로 정의되지 않음"을 의미합니다. 특수 멤버 함수가 선언되었지만 삭제 된 것으로 정의 된 상황이 있습니다.

  • 사용자 선언 생성자가없는 경우 기본 생성자가 자동 ​​생성됩니다 (§12.1 / 5).
  • C ++ 03에는 이동 생성자 또는 이동 할당 연산자가 없기 때문에 사용자 선언 이동 생성자 또는 이동 할당 연산자가 없으면 복사 생성자가 자동 ​​생성됩니다 (C ++ 03의 "항상"으로 단순화). §12.8 / 8).
  • 사용자 지정 이동 생성자 또는 이동 할당 연산자가없는 경우 복사 할당 연산자가 자동 ​​생성됩니다 (§12.8 / 19).
  • 사용자가 선언 한 소멸자가없는 소멸자는 자동 생성됩니다 (§12.4 / 4).

C ++ 11 이상 만 :

  • 사용자 생성 복사 생성자, 복사 할당 연산자 또는 소멸자가없고 생성 된 이동 생성자가 유효한 경우 (§12.8 / 10) 이동 생성자가 자동 ​​생성됩니다.
  • 사용자 지정 복사 생성자, 복사 할당 연산자 또는 소멸자가없고 생성 된 이동 할당 연산자가 유효한 경우 (예 : 상수 멤버를 할당 할 필요가없는 경우) 이동 할당 연산자는 자동 생성됩니다 (§12.8 / 21).

9
상속 된 소멸자는 계산됩니까? 빈 가상 소멸자가있는 기본 클래스가 있다고 가정 해보십시오. 서브 클래스에서 이동 생성자를 작성하지 못하게합니까? 대답이 예이면 기본 클래스에서 이동 생성자를 정의하면 도움이됩니까?
kamilk

10
const클래스에 멤버 가 있으면 생성자가 자동 ​​생성되는 것을 막을 수 있다고 언급해야한다고 생각합니다 .
nonsensickle

"특수 멤버 함수가 선언되었지만 삭제 된 것으로 정의 된 상황이 있습니다." 예를 들어 이동이 불가능한 const 또는 참조 멤버가있는 위치를 참조하십시오. 아니요, 사본이 적용되기 때문에 불가능합니다.
towi

이 포럼에서 하이퍼 링크를 전송하는 것이 제한되어 있다는 것을 알고 있습니다. 그러나 그것은 또한 좋은 기사입니다 - cplusplus.com/articles/y8hv0pDG을
bruziuz

클래스에 사용자가 선언 한 복사 할당 연산자 또는 사용자가 선언 한 소멸자를 가지고있는 경우 표준에서 "암시 적으로 기본 화 된 복사 생성자" 는 사용되지 않습니다 "( 12.8 클래스 객체 복사 및 이동 [class.copy] ).
sigy

98

아래 다이어그램이 매우 유용하다는 것을 알았습니다.

자동 생성자와 할당 연산자를위한 C ++ 규칙 에서 스티커 비트 - 제로 영웅의 규칙되기


아름다운. "독립"이란 무엇입니까? 무엇과 독립적입니까?
towi

8
사본 ctor / 할당은 서로 '독립적'입니다. 하나만 작성하면 컴파일러가 다른 하나를 제공합니다. 반대로 이동 ctor 또는 이동 할당을 제공하면 컴파일러는 다른 것을 제공하지 않습니다.
Marco M.

복사 작업이 독립적 인 이유가 무엇인지 궁금합니다. 역사적인 이유일까요? 또는 사본이 대상을 수정하지 않지만 이동은 수정한다는 사실?
RaGa__M

@Explorer_N 예, 이전 버전과의 호환성, 역사적인 이유. 오래 전에 디자인을 잘못 선택 했으므로 이제 버그를 찾기 어려운 "3 가지 규칙"(모두 생성자, 복사 할당 연산자 및 종종 소멸자 정의)과 같은 모범 사례가 필요합니다.
atablash

@MarcoM., 내가 이해하는 한, "만약 쓰는 경우 ..."조건에는 특수 멤버 기능을 = delete(명백하게) 또는 = default(나에게 덜 명확하게 ) 설정하는 두 가지 경우가 포함됩니다 . 내가 맞아?
엔리코 마리아 데 안젤리 스

2

C ++ 17 N4659 표준 초안

빠른 상호 표준 참조를 위해 다음 cppreference 항목의 "암시 적으로 선언 된"섹션을 살펴보십시오.

물론 동일한 정보를 표준에서 얻을 수 있습니다. 예를 들어 C ++ 17 N4659 표준 초안 :

15.8.1 "복사 / 이동 생성자"는 복사 생성자를 나타냅니다.

6 클래스 정의가 명시 적으로 복사 생성자를 선언하지 않으면 명시 적이 지 않은 것이 암시 적으로 선언됩니다. 클래스 정의가 이동 생성자 또는 이동 할당 연산자를 선언하면 암시 적으로 선언 된 복사 생성자가 삭제 된 것으로 정의됩니다. 그렇지 않으면 기본값 (11.4)으로 정의됩니다. 클래스에 사용자 선언 복사 할당 연산자 또는 사용자 선언 소멸자가 있으면 후자의 경우 더 이상 사용되지 않습니다.

이동 생성자 :

8 클래스 X의 정의가 이동 생성자를 명시 적으로 선언하지 않는 경우, 명시 적이 지 않은 것이 명시 적으로 선언 된 경우에만 기본값으로 선언됩니다.

  • (8.1) — X에는 사용자가 선언 한 복사 생성자가 없습니다.

  • (8.2) — X는 사용자가 지정한 복사 할당 연산자를 가지고 있지 않습니다.

  • (8.3)-X는 사용자가 지정한 이동 할당 연산자를 가지고 있지 않으며

  • (8.4) — X는 사용자가 선언 한 소멸자를 가지고 있지 않다.

15.8.2 "복사 / 이동 할당 연산자"는 복사 할당에 대해 말합니다.

2 클래스 정의가 복사 할당 연산자를 명시 적으로 선언하지 않으면 암시 적으로 선언됩니다. 클래스 정의가 이동 생성자 또는 이동 할당 연산자를 선언하면 암시 적으로 선언 된 복사 할당 연산자는 삭제 된 것으로 정의됩니다. 그렇지 않으면 기본값 (11.4)으로 정의됩니다. 클래스에 사용자 선언 사본 생성자 또는 사용자 선언 소멸자가 있으면 후자의 경우 더 이상 사용되지 않습니다.

그리고 이동 할당 :

4 클래스 X의 정의가 이동 할당 연산자를 명시 적으로 선언하지 않으면 다음과 같은 경우에만 암시 적으로 기본값으로 선언됩니다.

  • (4.1) — X에는 사용자가 선언 한 복사 생성자가 없습니다.
  • (4.2) — X는 사용자가 선언 한 이동 생성자를 가지고 있지 않습니다.
  • (4.3) — X에는 사용자가 지정한 사본 할당 연산자가 없으며
  • (4.4) — X에는 사용자가 선언 한 소멸자가 없습니다.

15.4 "소멸자"는 소멸자를 위해 다음과 같이 말합니다.

4 클래스에 사용자가 선언 한 소멸자가 없으면 소멸자는 암시 적으로 기본값 (11.4)으로 선언됩니다. 암시 적으로 선언 된 소멸자는 해당 클래스의 인라인 공용 멤버입니다.

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