带有auto_ptr的C ++初始化列表

时间:2012-09-27 15:14:05

标签: c++ smart-pointers

为什么编译和工作:

class MyObject {
public:
  MyObject() {}
};

struct ItemGood {
  int Number;
  MyObject *Object;

  ItemGood(int Number, MyObject *Object) {
    this->Number = Number;
    this->Object = Object;
  }
};

const ItemGood ItemGoodList[] =
{
  { 0, new MyObject() },
  { 1, new MyObject() }
};

这根本不编译:

class MyObject {
public:
  MyObject() {}
};

struct ItemBad {
  int Number;
  std::auto_ptr<MyObject> AutoObject;

  ItemBad(int Number, MyObject *Object) {
    this->Number = Number;
    AutoObject = std::auto_ptr<MyObject>(Object);
  }
};

const ItemBad ItemBadList[] =
{
  { 0, new MyObject() },
  { 1, new MyObject() }
};

编译器吐出的错误是:

  

没有匹配函数来调用'ItemBad :: ItemBad(ItemBad)

我不明白为什么某些东西试图调用该构造函数,我不明白这个初始化列表中实际发生了什么。

4 个答案:

答案 0 :(得分:1)

试试这个:

ItemBad(int Number, MyObject *Object) : Number(Number), AutoObject(Object) 
{}

似乎std::auto_ptr在您的平台上没有copy-constructor,因此必须在构造函数体之前初始化它。

答案 1 :(得分:1)

因为std::auto_ptr没有正确的拷贝构造函数,这意味着你的类没有正确的拷贝构造函数,这意味着它不能用临时构造 - 这正是你想要做的。

只是垃圾auto_ptr并移至unique_ptr

答案 2 :(得分:0)

此外,您应该避免使用这样的初始化列表:

{ 0, new MyObject() }

相反,请使用构造函数:

ItemBad(0, new MyObject())

例如,MSVC编译器会为您的“好”变体以及“坏”变体生成错误:只要您的类具有ctor,就必须使用它,而不是初始化列表。

答案 3 :(得分:0)

每个{ 0, new MyObject() }表达式都被构造函数调用ItemGood(int Number, MyObject *Object)替换,因此编译器会生成如下内容:

const ItemGood ItemGoodList[] =
{
  ItemGood(0, new MyObject()), // temporal 'ItemGood' 1 (const &)
  ItemGood(1, new MyObject())  // temporal 'ItemGood' 2 (const &)
};

然后调用ItemGood的编译器生成的复制结构体来填充每个ItemGood的数组槽,这里没有问题

ItemBad类声明包含成员变量std::auto_ptr<MyObject> AutoObject,并且如另一个答案中所指出的,std::auto_ptr没有复制构造函数,因此编译器无法创建其 ItemBad的编译器生成的复制结构。当应用先前的逻辑时,我们得到与ItemGood

相同的表达式替换
const ItemBad ItemGoodList[] =
{
  ItemBad(0, new MyObject()), // temporal 'ItemBad' 1 (const &)
  ItemBad(1, new MyObject())  // temporal 'ItemBad' 2 (const &)
};

但是这里我们没有copy-constructor,所以你报告的错误发生了,使用ItemBad构造函数中的初始化列表将无法解决问题并且删除MyObject赋值不会解决问题

ItemBad(int Number, MyObject *Object) {
   this->Number = Number;
   // AutoObject = std::unique_ptr<MyObject>(Object);  This comment doesn't solve the problem
}

如前所述更改为unique_ptr,或使用提升shared_ptr