#include <iostream>
class derive1{
public:
derive1() = default;
~derive1() = default;
virtual void func() { std::cout << "derive 1" << std::endl; }
};
class derive2 {
public:
derive2() = default;
~derive2() = default;
virtual void func() { std::cout << "derice 2" << std::endl; }
};
union classUnion {
classUnion() {};
~classUnion() {};
derive1 obj1;
derive2 obj2;
};
int main() {
classUnion u1;
u1.obj1.func(); // <-- OK print 'derive 1'
derive1 &dev1 = u1.obj1;
dev1.func(); // <-- OK print 'derive 1'
derive1 *ptr = &(u1.obj1);
ptr->func(); // <-- core dump/seg fault
return 0;
}
我认为 C++11 允许非平凡的构造函数(带有虚函数)。
我看不出这里有什么问题。
我用
“g++ -std=c+11 test.cpp”来编译它(gcc 4.8 和 gcc 5.0)。
问题是您从未初始化联合内的对象。至少,让它发挥作用的最简单方法是以下小调整:
union classUnion {
classUnion() {};
~classUnion() {};
derive1 obj1={}; // unions can have one inline initializer
derive2 obj2;
};
但是,如果您这样做:
int main() {
classUnion u1;
u1.obj1 = derive1{};
...
}
它仍然会崩溃。原因是因为您正在分配给一个未初始化的对象,特别是您有一个用户定义的析构函数(即虚拟析构函数)。
考虑以下:
(http://en.cppreference.com/w/cpp/language/union http://en.cppreference.com/w/cpp/language/union.)
如果联合的成员是具有用户定义构造函数的类并且
析构函数,切换活动成员,显式析构函数和
通常需要放置新的:
因此,要实际使用具有虚拟函数的类(通常需要虚拟析构函数),您将需要使用放置新的和手动销毁调用,如下所示:
int main() {
classUnion u1;
new (&u1.obj1) derive1{};
... // use obj1
u1.obj1.~derive1();
new (&u1.obj2) derive2{};
... // use obj2
u1.obj2.~derive2();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)