匿名联合中类成员的初始化
initialization of class member in anonymous union
我观察到ar.p()
:行出现以下代码分段故障
#include <iostream>
class A
{
public:
virtual void p() { std::cout<<"A!n"; }
};
class B : public A
{
public:
void p() { std::cout<<"B!n"; }
};
struct Param
{
enum {AA, BB} tag;
union {
A a;
B b;
};
Param(const A &p)
: tag(AA) {a = p;}
A &get() {
switch(tag) {
case AA: return a;
case BB: return b;
}
}
};
int main() {
A a;
a.p();
Param u(a);
A &ar = u.get();
ar.p();
}
但是,当我将Param
构造函数更改为:时
Param(const A &p)
: tag(AA), a(p) {}
它不再出错。
我认为这与工会成员a
的vtable ptr的初始化方式有关,但我想更好地理解这个错误。
关于coliru:http://coliru.stacked-crooked.com/a/85182239c9f033c1
联合没有隐式构造函数,您必须将自己的构造函数添加到初始化联合的一个成员的联合中。我认为这是因为编译器不知道您是要初始化a
还是b
。您可能还需要一个赋值运算符和析构函数。另请参阅这个问题:如果联合的一个成员没有删除默认构造函数,为什么它会删除默认构造函数;什么都没有?
构造函数应该使用placement new,或者可以使用成员初始值设定项来构造一个联合成员,就像在备选构造函数中所做的那样。
如果之后要将某个内容分配给b
,则必须使用a.~A()
销毁a
,然后使用placement new初始化b
。
如果联合中有具有非平凡析构函数的成员,则该联合必须具有一个析构函数,该析构函数调用当时使用的成员的析构函数。
在原始代码中,赋值运算符和p()
方法在没有首先运行构造函数的情况下被调用,从而导致崩溃。
相关文章:
- C++成员初始化
- c++构造函数成员初始化:传递参数
- C++正确的指针成员初始化
- 将另一个类的对象传递到当前类C++的构造函数中(不是成员初始化)
- WinLamb 错误:成员初始化非法
- 使用其他成员初始化结构的成员?
- C++模板类静态成员初始化
- 解释了构造函数成员初始化列表
- 如何在成员初始化列表中声明共享指针
- C++入门5版:使用get成员初始化另一个与shared_ptr无关的对象
- C++11 默认类成员初始化与初始值设定项列表同时
- 调用非默认构造函数作为成员初始化
- C++模板成员初始化:用右值移动构造,但用左值移动引用
- 类成员初始化C++
- 在成员初始化列表中,我可以创建对列表中不在列表中的成员变量的引用
- C :(不重复)积分静态成员初始化(不仅是声明!),导致链接器错误,原因
- 如何调用成员初始化器列表中参考成员的构造函数
- C 构造函数采用成员初始化器
- 与其他静态const成员初始化静态常量成员
- 静态内联成员初始化顺序