我已经使用了boost :: variant一段时间了,现在我想弄清楚它是如何在内部工作的。我写了一个简单的测试,我无法理解结果。这是(简化)
struct my_type
{
my_type(){ cout << (size_t)this << " construction"; }
~my_type(){ cout << (size_t)this << " destruction"; }
};
int main()
{
variant<int, my_type> x;
x = my_type();
}
此类程序的输出是
140736940365327 construction <-- A
140736940365236 destruction <-- ?
140736940365327 destruction <-- A
140736940365332 destruction <-- ?
为什么析构函数不像构造函数那样多次被调用?由于析构函数是在堆上调用的,我知道这可能不是段错误,但在我看来这种行为是危险的。我错过了什么吗?这与boost :: variant的“备份”机制有关吗?
答案 0 :(得分:2)
您只定义了默认构造函数,但当然也可以使用各种参数调用构造函数。由于您没有显式定义复制构造函数(一个带有const my_type&
的构造函数),因此编译器会隐式为您生成一个。如果添加自己的复制构造函数,您应该看到它用于构造另外两个神秘对象:
struct my_type
{
my_type(){ cout << (size_t)this << " construction"; }
my_type(const my_type&){ cout << (size_t)this << " copy construction"; }
~my_type(){ cout << (size_t)this << " destruction"; }
};
实际上,如果您使用的是C ++ 11编译器,则隐式生成的移动构造函数将负责某些新对象。如果您提供上面的复制构造函数,则不再生成隐式移动构造函数,因此它们都显示为复制构造。但是,如果你也提供了一个移动构造函数,你会发现它被调用:
struct my_type
{
my_type(){ cout << (size_t)this << " construction"; }
my_type(const my_type&){ cout << (size_t)this << " copy construction"; }
my_type(my_type&&){ cout << (size_t)this << " move construction"; }
~my_type(){ cout << (size_t)this << " destruction"; }
};