我正在使用匿名联盟实现一个名为QVariant
的类Variant
类:
class Variant
{
public:
// …
~Variant();
// …
private:
Type _type;
union
{
int _int;
uint64_t _uint64;
float _float;
void* _ptr;
};
};
尝试将Variant::~Variant()
成员删除为Variant::_ptr
时,String*
会出现段错误:
Variant::~Variant()
{
if (_type == Type::String)
delete reinterpret_cast<String*>(_ptr);
else if (_type == Type::Date)
delete reinterpret_cast<Date*>(_ptr);
// …
}
以这种方式分配:
Variant::Variant(const String& str)
: _type(Type::String),
_ptr(new String(str))
{}
奇怪的是,在GDB中,在析构函数堆栈框架上,我无法访问union成员,但我可以访问Variant::_type
成员。
(gdb) frame
#0 0x0000000000527700 in Variant::~Variant (this=0x7fffec0337a0, __in_chrg=<optimized out>) at Sources/Types/Variant.cpp:85
85 delete reinterpret_cast<String*>(_ptr);
(gdb) p _ptr
No symbol "_ptr" in current context.
(gdb) p _int
No symbol "_int" in current context.
(gdb) p _float
No symbol "_float" in current context.
(gdb) p _type
$2 = Variant::String
似乎联盟已被删除,因此,它会尝试删除无法访问的_ptr
。但为什么呢?
答案 0 :(得分:3)
我的通灵调试功能告诉我你没有实现自己的拷贝构造函数,默认的只是复制指针而不是分配新的内存。然后,当原件的副本被销毁时,会导致双重删除。
但除非这是一项练习,否则只需使用boost::variant
或boost::any
,因为它们已经是非常完善的解决方案。