2011-01-31 6 views
3

가능한 중복 : 나는 복수를 사용할 때 컴파일러가 서로 다른 초기 값을 처리 할 방법에 대해 궁금하네요 안녕하세요
gcc c++ virtual inheritance problem가상 기본 클래스 및 초기화 목록

,

가상 기본 클래스의 상속. 상속 방식 악명 높은 '공포의 다이아몬드'를 고려 JoinBase 2 부 것을 방지하기 위해

 Base 
    /\ 
    / \ 
    D1  D2 
    \ /
    \/
    Join 

, 나는 (예를 들어, here 참조) D1D2 가상 상속을 사용합니다. 이제 Base 추상적 아니라고 할 수 있지만 생성자에서 초기화되는 멤버 필드있다 :

class Base { 
public: 
    Base(int x_) {x = x_;}; 
    virtual ~Base(){}; 

public: 
    int x; 
}; 

class D1 : public virtual Base { 
public: 
    D1() : Base(1) {}; 
    virtual ~D1(){}; 
}; 

class D2 : public virtual Base { 
public: 
    D2() : Base(2) {}; 
    virtual ~D2(){}; 
}; 

class Join : public D1, public D2 { 
public: 
    Join(){}; 
    ~Join(){}; 
}; 

int main() 
{ 
    Join j; 
    cout << j.x << endl; 

    return 0; 
} 

출력이 1이 될 것인가를하거나 컴파일러 의존?

+1

새로운 테스트 케이스 코드는'Join j; cout << j.x;'. –

+0

@Charles,이 질문은 GCC와 관련이 없으므로 엄격하게 중복되지는 않습니다. 같은 문제를 다루지 만 대답은 컴파일러 독립적입니다. –

+0

@ SergeyTachenov : 그 질문은 gcc에만 해당되는 것이 아니며, 단지 약간의 오해의 소지가있는 제목에 gcc가있는 것입니다. –

답변

5

컴파일 중입니다. 가상베이스는 가장 파생 된 클래스 인 Join에 의해 초기화됩니다. Join은 명시 적으로 Base을 초기화하지 않지만 Base에는 액세스 가능한 기본 생성자가 없습니다.

[클래스의 정의가 ;으로 끝나야하기 때문에 컴파일러가되지 않지만 오타라고 가정했습니다. main 또한 int을 반환해야 내가 j.xj->x의 오타라고 가정했습니다.]

+0

오타가 수정되었습니다. – bavaza

2

가상 상속이 때 가상 기본 클래스를 초기화해야 최종 클래스입니다.

따라서 가입의 생성자는 자료를 구축해야합니다

class Join : public D1, public D2 
    { 
    public: 
     Join() : Base(3){} // or whatever value 
     ~Join(){} 
    }; 

그것은 클래스는 일반적으로 즉각적인베이스 클래스를 초기화 규칙에 대한 예외입니다.

(그 외에 main에서이 int를 반환해야합니다 그리고 당신은 j->x을 할 필요가 없습니다 j.x j는 포인터뿐만 아니라 사실로는 new 전화로 당신이 그것을 delete 있어야합니다 같은) 자료가 없기 때문에

+0

당신은 17 초 만에 나를 때려 : D 조 – Palmik

1

을 암시 적 생성자 모두 C1C2 가상 기지는이 같은 변경 (그리고 찰스 베일리에 의해 지적 클래스 선언의 휴식 후 세미콜론을 추가)해야 할 것입니다

class Join : public D1, public D2 { 
public: 
    Join() : Base(3) {}; 
    ~Join(){}; 
}; 

int main() 
{ 
    Join j; 
    cout << j.x << endl; 
} 

그런 다음 3을 표준 출력에 출력합니다.

관련 문제