为什么编译和工作:
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)
我不明白为什么某些东西试图调用该构造函数,我不明白这个初始化列表中实际发生了什么。
答案 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