gcc 4.5.1 虚拟继承问题
让我们从代码片段开始:
#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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这一定是编译器错误。我还测试了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.
我测试了几种较旧的版本(最高可达 4.3 - 有效) - 手头没有 4.4 系列(将在早上测试),但我同意,这似乎是一个错误(而不是在数据库中),也许值得提高它。
但我注意到,如果您更改第一个关系(
Base1
到God
从虚拟到非虚拟),那么该示例将按预期工作。我想这取决于你的需求,你是否会直接从最派生的类中调用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
toGod
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 ofGod
from the most derived class (though I've never seen this approach before...)