2012-02-08 13 views
6

Hãy bắt đầu từ đoạn mã:gcc 4.5.1 vấn đề thừa kế ảo

#include <iostream> 

struct God{ 
    God(){_test = 8;} 
    virtual ~God(){} 
    int _test; 
}; 

struct Base1 : public virtual God{ 
    //Base1(){std::cout << "Base1::Base1" << std::endl;} //enable this line to fix problem 
    virtual ~Base1(){} 
}; 

struct Base2 : public virtual Base1{ 
    virtual ~Base2(){} 
}; 

struct A1 : public virtual Base2{ 
    A1(){std::cout << "A1:A1()" << std::endl;} 
    virtual ~A1(){}; 
}; 

struct A2 : public virtual Base2{ 
    A2(){std::cout << "A2:A2()" << std::endl;} 
    virtual ~A2(){}; 
}; 


struct Derived: public virtual A1, public virtual A2{ 
    Derived():Base1(){std::cout << "Derived::Derived()" << std::endl;} 
    Derived(int i){std::cout << "Derived(i)::Derived(i)" << std::endl;}   
    virtual ~Derived(){} 
}; 


int main(){ 

    God* b1 = new Derived(); 
    std::cout << b1->_test << std::endl; //why it prints 0? 

    God* b2 = new Derived(5); 
    std::cout << b2->_test << std::endl; 

    return 0; 
} 

Biên soạn với GCC 4.5.1 và 4.6.1 Sự khác biệt duy nhất giữa nhà xây dựng của lớp nguồn gốc là người đầu tiên khẳng định một cách rõ ràng mà Base1 constructor nên được gọi. Tôi hy vọng rằng cả hai cout in main() in 8. Thật không may là người đầu tiên in 0 !.

Tại sao?

Nếu tôi bật định nghĩa rõ ràng về hàm tạo Base1, nó sẽ khắc phục sự cố. Nếu tôi loại bỏ thừa kế ảo trong Định nghĩa lớp có nguồn gốc (lớp Xuất phát: công khai A1, công khai A2), nó cũng hoạt động. Hành vi mong đợi?

Sự cố không thể quan sát được theo GCC 3.4.4 hoặc trình biên dịch của Microsoft (VS)

+0

Tôi nhận được "8" với gcc 3.4.6 – Beta

+0

Chắc chắn có vẻ như bạn đã kích hoạt lỗi gcc cho tôi. –

Trả lời

1

Đây phải là lỗi trình biên dịch. Tôi cũng đã thử nghiệm GCC 4.2.1 và kết quả là 8 cả hai trường hợp.

1

Tôi đã thử nghiệm với một số hương vị cũ hơn (lên đến 4.3 - hoạt động) - không có chuỗi phim 4.4 (sẽ kiểm tra vào buổi sáng), nhưng tôi đồng ý, đây dường như là lỗi (chứ không phải db), có lẽ đáng để nâng cao nó.

Tôi nhận thấy rằng nếu bạn thay đổi mối quan hệ đầu tiên (Base1 thành God từ ảo thành không ảo) thì ví dụ sẽ hoạt động như mong đợi. Tôi đoán điều này phụ thuộc vào nhu cầu của bạn, cho dù bạn sẽ trực tiếp gọi ctor của God từ lớp có nguồn gốc cao nhất (mặc dù tôi chưa bao giờ thấy cách tiếp cận này trước ...)