gcc 4.5.1 虚拟继承问题

发布于 2025-01-04 04:09:42 字数 1403 浏览 1 评论 0原文

让我们从代码片段开始:

#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;
}

用 GCC 4.5.1 和 4.6.1 编译 Derived 类的构造函数之间的唯一区别是第一个构造函数显式声明应调用哪个 Base1 构造函数。 我希望 main() 中的两个 cout 都打印 8。不幸的是,第一个打印 0!。

为什么?

如果我启用 Base1 构造函数的显式定义,则可以解决问题。 如果我删除派生类定义中的虚拟继承(派生类:public A1,public A2),它也可以工作。 这是预期的行为吗?

在 GCC 3.4.4 或 Microsoft 编译器 (VS) 下无法观察到该问题

Let's start from code snippet:

#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;
}

Compiled with GCC 4.5.1 and 4.6.1
The only difference between constructors of Derived class is that first one explicitly states which Base1 constructor should be called.
I would expect that both cout in main() print 8. Unfortunately the first one prints 0!.

Why?

If I enable explicit definition of Base1 constructor it fixes the problem.
If I remove virtual inheritance in Derived class definition (class Derived: public A1, public A2) it works as well.
Is it expected behaviour?

The issue is not observable under GCC 3.4.4 or Microsoft compiler (VS)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不喜欢何必死缠烂打 2025-01-11 04:09:42

这一定是编译器错误。我还测试了GCC 4.2.1,两种情况的结果都是8。

This must be a compiler bug. I also tested GCC 4.2.1 and the result is 8 both cases.

最单纯的乌龟 2025-01-11 04:09:42

我测试了几种较旧的版本(最高可达 4.3 - 有效) - 手头没有 4.4 系列(将在早上测试),但我同意,这似乎是一个错误(而不是在数据库中),也许值得提高它。

但我注意到,如果您更改第一个关系(Base1God 从虚拟到非虚拟),那么该示例将按预期工作。我想这取决于你的需求,你是否会直接从最派生的类中调用God的ctor(虽然我以前从未见过这种方法......)

I tested with several older flavours (up to 4.3 - which works) - don't have a 4.4 series to hand (will test in the morning), but I agree, this appears to be a bug (and not in the db), probably worth raising it.

I notice though that if you change the first relationship (Base1 to God from virtual to non-virtual), then the example works as expected. I guess this depends on your needs, whether you will directly call the ctor of God from the most derived class (though I've never seen this approach before...)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文