2013-02-23 46 views
0

我已经使用了boost :: variant一段时间,现在我正在试图弄清楚它是如何在内部工作的。我写了一个简单的测试,我无法理解结果。这里是(简化)boost ::变体对象构造计数VS销毁计数

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的“备份”机制有关吗?

+2

向您的课堂添加复制构造函数。 – Mat 2013-02-23 12:22:23

回答

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"; } 
}; 
+0

那么默认的构造函数是在我没有定义的时候隐式调用的? – neodelphi 2013-02-23 12:27:21

+0

@neodelphi是的,编译器为你隐式生成一个拷贝构造函数,如果你没有定义它的话。 – 2013-02-23 12:28:33

+0

谢谢,解释一下吧! – neodelphi 2013-02-23 12:29:50