그 이유는 클래스에 사용자 정의 생성자가 없으면 POD가 될 수 있고 POD 클래스는 기본적으로 초기화되지 않기 때문입니다. 따라서 초기화되지 않은 POD의 const 객체를 선언하면 어떻게 사용됩니까? 그래서 저는 표준이이 규칙을 시행하여 객체가 실제로 유용 할 수 있도록한다고 생각합니다.
struct POD
{
int i;
};
POD p1; //uninitialized - but don't worry we can assign some value later on!
p1.i = 10; //assign some value later on!
POD p2 = POD(); //initialized
const POD p3 = POD(); //initialized
const POD p4; //uninitialized - error - as we cannot change it later on!
하지만 수업을 비 -POD로 만드는 경우 :
struct nonPOD_A
{
nonPOD_A() {} //this makes non-POD
};
nonPOD_A a1; //initialized
const nonPOD_A a2; //initialized
POD와 비 -POD의 차이점에 유의하십시오.
사용자 정의 생성자는 클래스를 POD가 아닌 것으로 만드는 한 가지 방법입니다. 이를 수행 할 수있는 몇 가지 방법이 있습니다.
struct nonPOD_B
{
virtual void f() {} //virtual function make it non-POD
};
nonPOD_B b1; //initialized
const nonPOD_B b2; //initialized
nonPOD_B는 사용자 정의 생성자를 정의하지 않습니다. 그것을 컴파일하십시오. 다음과 같이 컴파일됩니다.
그리고 가상 기능에 주석을 달면 예상대로 오류가 발생합니다.
글쎄, 당신은 그 구절을 오해했다고 생각합니다. 먼저 다음과 같이 말합니다 (§8.5 / 9).
객체에 대해 초기화 프로그램이 지정되지 않고 객체가 (가능하면 cv-qualified) non-POD 클래스 유형 (또는 배열) 인 경우 객체는 기본값으로 초기화됩니다. [...]
cv-qualified 유형일 수있는 비 POD 클래스에 대해 이야기 합니다. 즉, 초기화 프로그램이 지정되지 않은 경우 POD가 아닌 개체는 기본적으로 초기화됩니다. 그리고 기본 초기화는 무엇입니까? 비 POD의 경우 사양에 (§8.5 / 5),
T 유형의 객체를 기본 초기화한다는 것은 다음을 의미합니다.
— T가 비 POD 클래스 유형 (9 절)이면 T에 대한 기본 생성자가 호출됩니다 (T에 액세스 할 수있는 기본 생성자가 없으면 초기화 형식이 잘못됨).
사용자 정의 또는 컴파일러 생성 여부에 관계없이 T의 기본 생성자 에 대해 이야기 합니다.
이것에 대해 확실하다면 다음에 나오는 사양 ((§8.5 / 9),
[...]; 객체가 const 한정 유형이면 기본 클래스 유형은 사용자가 선언 한 기본 생성자를 가져야합니다.
따라서이 텍스트 는 객체가 const-qualified POD 유형이고 초기화 프로그램이 지정되지 않은 경우 프로그램의 형식이 잘못됨을 의미 합니다 (POD가 기본적으로 초기화되지 않기 때문에).
POD p1; //uninitialized - can be useful - hence allowed
const POD p2; //uninitialized - never useful - hence not allowed - error
그건 그렇고, 이것은 POD가 아니기 때문에 잘 컴파일 되고 default-initialized 될 수 있습니다 .
a.하지만 gcc-4.3.4는이를 허용하는 경우에도 허용합니다 ( ideone.com/uHvFS 참조 ).