0

我已经使用 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 的“备份”机制有关吗?

4

1 回答 1

2

您只定义了一个默认构造函数,但当然也可以使用各种参数调用构造函数。由于您没有显式定义复制构造函数(接受 a 的构造函数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"; }
};
于 2013-02-23T12:24:47.617 回答