2017-10-23 11 views
4

기본 클래스 생성자와 상속을 호출하는 개념을 구현하려고합니다. 다음 코드를 작성했지만 클래스 A의 기본 생성자를 선언하지 않으면 오류가 발생합니다. 나는 왜 오류가 발생하는지 궁금해. 당신이 B의 인스턴스를 만들려면,이 자동으로 슈퍼 클래스의 인스턴스를 생성하기 때문에기본 클래스 생성자를 호출하는 동안 기본 생성자 선언

#include <iostream> 
using namespace std; 

class A 
{ 
    int a; 
    public: 
    A() {} //Default Constructor 
    A(int x) 
    { 
     a=x;cout<<a; 
     cout<<"A Constructor\n"; 
    } 
}; 
class B: virtual public A 
{ 
    int b; 
    public: 
    B(int x) 
    { 
     b=x;cout<<b; 
     cout<<"B Constructor\n"; 
    } 
}; 
class C: virtual public A 
{ 
    int c; 
    public: 
    C(int x) 
    { 
     c=x;cout<<c; 
     cout<<"C Constructor\n"; 
    } 
}; 
class D: public B,public C 
{ 
    int d; 
    public: 
    D(int p,int q,int r,int s):A(p),B(q),C(r) 
    { 
     d=s;cout<<d; 
     cout<<"D Constructor\n"; 
    } 
}; 
int main() 
{ 
    D d(1,2,3,4); 
    return 0; 
} 
+2

구체적으로 어떤 오류가 있습니까? – user0042

+1

'A' 디폴트 생성자는'B'와'C' 클래스에서 암묵적으로 사용됩니다. 나는이 질문이 수년 전에 터져 나온 것을 기억하고 있기 때문에 형식적인지 확신 할 수 없다. 아마도 대답은 'B'와 'C'의 암시 적 초기화가 존재하지 않는 것으로 간주되어야한다는 것이다. 어쨌든 이러한 초기화는 사실상 무시됩니다. 왜냐하면 가상 기본 클래스가 가장 파생 된 클래스 ('D')에서 초기화되기 때문입니다. 예, C++의 가상 상속 개념은 약간 부정합니다. –

답변

2

당신은 하위 클래스에서 상위 클래스의 생성자를 호출 해달라고하면 는 슈퍼 클래스는 기본 생성자가 있어야합니다 기본 생성자가 없으면 불가능합니다.

1

잠시 동안 단순화하고 클래스 CD의 존재를 잊어 봅시다.

당신이 유형 B의 객체를 생성하는 경우

B b(10); 

로는 B::B(int)를 사용합니다. B::B(int)의 구현에서 BA 부분은 어떻게 든 초기화되어야합니다. 당신은이 :에 해당합니다

B(int x) 
{ 
    b=x;cout<<b; 
    cout<<"B Constructor\n"; 
} 

: A 이후

B(int x) : A() 
{ 
    b=x;cout<<b; 
    cout<<"B Constructor\n"; 
} 

는 기본 생성자가없는 컴파일러가 제대로 그 오류로보고합니다.

당신은 사용하여 해당 문제를 해결 수 : B의 생성자에서 A(int)에 다른 값을 통과 할 수 있도록하고 싶습니다 경우

B(int x) : A(0) 
{ 
    b=x;cout<<b; 
    cout<<"B Constructor\n"; 
} 

, 당신은 사용자가 두 개의 인수를 사용하여 B 구성 할 수 있도록해야합니다.

B(int x, int y = 0) : A(y) 
{ 
    b=x;cout<<b; 
    cout<<"B Constructor\n"; 
} 
+0

그러나 클래스 'B'는 OP 코드에서 가장 많이 파생 된 클래스로 사용되지 않습니다. 개별 컴파일에 대한 지원이 실질적으로 해당 케이스에 특별한 규칙이 필요하지 않다고 주장 할 수 있습니다. 그러나 나는 그렇게 확신하지 않는다. –

+0

@ Cheersandhth.-Alf의 경우,'B'가 인스턴스화되었는지 또는'D'가 인스턴스화되는지에 관계없이'B (int) '를 올바르게 처리해야합니다. –

+0

@ R.Sahu : 대부분의 파생 클래스로 B의 경우에는 * 다른 작업을 수행하고 B는 기본 클래스의 경우를 수행합니다. 후자의 경우 반드시 A 생성자를 호출하지는 않습니다. 그것은 가장 파생 된 클래스에서 호출됩니다. 다른 동작을 수행하는 한 가지 방법은'A()'를 호출할지 여부를 동적으로 검사하는 B 생성자에 대한 코드를 생성하는 것입니다. 또 다른 방법은 가장 유추 된 클래스로서 B의 인스턴스 대신에'A()'를 호출하는 것입니다. 후자의 경우 링커 오류를 피할 수 있습니다. 표준이 허용/보증하는 것에 대한 질문은 그러므로 열려 있습니다. –