2012-03-28 3 views
62

다음 코드에서 daughter 유형의 객체를 인스턴스화 할 때 기본 grandmother() 생성자가 호출되는 이유를 모르겠습니까?기본 생성자가 가상 ​​상속에서 호출되는 이유는 무엇입니까?

grandmother(int) 생성자 중 하나 (내 mother 클래스 생성자의 사양을 따르기 위해)를 호출해야하거나이 코드가 가상 상속으로 인해 컴파일되지 않아야한다고 생각했습니다.

여기서 컴파일러는 자동으로 grandmother 기본 생성자를 내 뒤에서 호출하지만, 결코 요구하지 않았습니다.

#include <iostream> 

class grandmother { 
public: 
    grandmother() { 
     std::cout << "grandmother (default)" << std::endl; 
    } 
    grandmother(int attr) { 
     std::cout << "grandmother: " << attr << std::endl; 
    } 
}; 

class mother: virtual public grandmother { 
public: 
    mother(int attr) : grandmother(attr) { 
     std::cout << "mother: " << attr << std::endl; 
    } 
}; 

class daughter: virtual public mother { 
public: 
    daughter(int attr) : mother(attr) { 
     std::cout << "daughter: " << attr << std::endl; 
    } 
}; 

int main() { 
    daughter x(0); 
} 
+0

어떤 컴파일러 (및 버전)입니까? 어떤 주장을 가지고 컴파일 했습니까? – orlp

+0

gcc 4.6.3 20120306 (Red Hat 4.6.3-2) (fedora 15에서) 인수는 다음과 같습니다. 인수 : -O0 -g3 -Wall -c -fmessage-length = 0 –

+0

g ++ 4.1.2에 동일한 문제가 있습니다. http : // codepad.org/L0jBXfSP – orlp

답변

66

가상 상속을 사용할 때 가상 기본 클래스의 생성자는 가장 파생 클래스의 생성자가 직접 호출합니다. 이 경우 daughter 생성자는 grandmother 생성자를 직접 호출합니다.

초기화 목록에 grandmother 생성자를 명시 적으로 호출하지 않았으므로 기본 생성자가 호출됩니다. 올바른 생성자를 호출하려면 다음과 같이 변경하십시오. 참조 :

daugther(int attr) : grandmother(attr), mother(attr) { ... } 
+2

그건 완전히 의미가 있습니다, 고마워요! 계층 구조의 모든 생성자는 각각의 자식 클래스가 아니라 마지막 클래스에서 호출됩니다. 절대로 그렇게 생각하지 않았습니다. 때로는 C++ 사양이 까다로울 수 있습니다 ... –

+0

감사합니다! 따라서 가상 상속의 경우 가장 좋은 방법은 체인의 모든 생성자를 수동으로 호출하는 것입니다. –

+0

우수 답변! 고마워! –