2014-04-29 3 views
1

제 4 클래스의 생성자를 어떻게 호출해야하는지 궁금합니다. 클래스 A는 기본 클래스이고 클래스 B와 C는이를 상속합니다.C++ 다이아몬드 상속 생성자?

ClassA::ClassA(const string &nam, const string &ide, double bal) 
     :name(nam), id(ide), balance(bal) 
{ 
} 

ClassB::ClassB(const string &nam, const string &ide, double bal) 
     :ClassA(nam, ide, bal) 
{ 
} 
ClassC::ClassC(const string &nam, const string &ide, double bal) 
       :ClassA(nam, ide, bal) 
{ 
} 

지금 내 4 클래스는 클래스 B와 클래스 C 모두가 어떻게 내 클래스 D에 대한 생성자를 호출하기로하고 상속?

여기에 표시되지는 정상 또는 가상 상속을 사용할지 여부를 무엇

ClassD::ClassD(const string &nam, const string& ide, double bal) 
     :ClassA(nam, ide, bal), ClassB(), ClassC() 
{ 
} 
+0

는 * 당신이 얻고; 나는 할 것이다. 당신의'ClassB' 또는'ClassC' 생성자 중 * 어느 쪽이 ** no ** 매개 변수를 취하는 것처럼 보이나요 ?? 그래, 나도 마찬가지야. 그렇다면 왜'ClassB()'와'ClassC() '를 호출할까요? 선언 된 생성자를 사용하십시오. 즉, 링크 된 질문의 모든 내용과 게시 된 답변이 적용되므로 신중하게 읽으십시오. – WhozCraig

+0

Im 어떤 생성자를 호출 할 것인지, 어떤 생성자를 호출하지 않을 것인지에 관해서는 매우 혼란 스럽습니까? ClassA 생성자는 기본 클래스이기 때문에 호출해야한다는 것을 이해합니다.하지만 클래스 B와 C 생성자를 호출하지 않습니다. 그리고 만약 그렇다면, 나는 인수를 공란으로 남겨 두는가? 그래서 나는 Im이 그 오류를 얻는다고 생각한다. * 모든 가상 상속 구문은 내 .h 파일에 포함되어 있습니다. – user3582405

답변

1

"A) ClassB가 :: ClassB가 (에 호출 일치 기능을"나는이 방법을 시도하지만 난 수 없습니다. 이 생성자의 부르심에 큰 영향을 미치지 :

  1. 정상적인 상속을 사용하는 경우, 당신은 ClassD의 각 인스턴스 내에서 ClassA 경우가 있습니다. 하나는 ClassB 인스턴스의 일부이고 다른 하나는 ClassC 인스턴스의 일부입니다. 따라서 각 중간 클래스는 자체 생성자 호출을 사용하여 자체 기본 인스턴스를 구성합니다.

    그러나 이것은 당신이 성취하고자하는 것이 아닙니다. 뇌를 매듭 짓는 가장 확실한 방법 외에도 많은 문제가 발생할 것입니다. 그 중 가장 작은 것은 ClassD의 인스턴스에서 ClassA의 멤버에 액세스하려는 거의 모든 시도가 모호함으로 인해 오류를 생성합니다. 컴파일러는 두 인스턴스 중 어느 인스턴스에서 멤버를 조회할지 간단히 알지 못합니다.

  2. 가상 상속을 사용하는 경우 개체에 ClassA이라는 단일 인스턴스 만 있습니다. 따라서 ClassB의 생성자도 ClassC의 생성자도 공유베이스를 구성하지 않으며 ClassA은 두 번 생성됩니다. 대신 ClassA은 다른 두 기본 생성자를 호출하기 전에 ClassD의 생성자에서 직접 생성되므로 ClassA()에 대한 호출을 기본 생성자가 수행하지 않는 경우 ClassD의 초기화 자 목록에 추가해야합니다. 귀하의 코멘트에 대한 응답으로


는 :
당신은 당신이 ClassBClassC의 생성자에서 호출 ClassA에 기본 생성자를 추가 할 수 있습니다. ClassDClassA의 전체 생성자를 호출 할 수 있으므로 ClassBClassC의 생성자를 통해 인수를 전달할 필요가 없습니다. ClassD의 오브젝트 만 구성하는 경우 기본 생성자 ClassBClassC의 정의에 대해 제공되어야하더라도 ClassA의 기본 생성자는 호출되지 않습니다.당신이 볼 수 있듯이

#include <iostream> 

class A { 
    public: 
     A() { std::cout << "A::A()\n"; } //Not used, but required. 
     A(int) { std::cout << "A::A(int)\n"; } 
}; 

class B : public virtual A { 
    public: 
     B() { std::cout << "B::B()\n"; } 
     B(int) : A(1) { std::cout << "B::B(int)\n"; } //Not required. 
}; 

class C : public virtual A { 
    public: 
     C() { std::cout << "C::C()\n"; } 
     C(int) : A(1) { std::cout << "C::C(int)\n"; } //Not required. 
}; 

class D : public B, public C { 
    public: 
     D(int) : A(1) { std::cout << "D::D(int)\n"; } 
}; 

int main() { 
    D foo(1); 
} 

이 프로그램의 출력은 A::A()BC이 건설 기본이며, 그렇지 않은 경우에도 호출되지 않습니다,

A::A(int) 
B::B() 
C::C() 
D::D(int) 

입니다 :

다음 코드를 고려 매개 변수를 통과해야합니다. A::A(int)D 클래스에서 직접 호출됩니다.

+0

클래스 B와 C에 가상 상속을 포함 시켰습니다. ClassD 생성자에 문제가 있습니다. ClassB와 C는 classA와 똑같은 매개 변수를 사용하여 호출합니다. 그래서 4 번째 클래스가 동일한 매개 변수를 가지고, classA 생성자를 B와 C로 호출합니까? 또는 A 만 빼고 B와 C는 생략합니까? – user3582405

+0

귀하의 의견에 대한 답변을 직접 답변에 추가했습니다. 예제가 충분히 설명되기를 바랍니다. – cmaster

1

과 같이 선언한다 : 링크 된 질문을 포함하여 다른 사람이, 실제 * 오류 메시지를 해결하지 않기 때문에

class ClassB: public virtual Class A 
{ 
    ... 
}; 
class ClassC: public virtual Class A 
{ 
    ... 
}; 
class ClassD: public ClassB, ClassC 
{ 
... 
};