2012-09-27 97 views
1

如何走到這一步編譯和工作原理:C++初始化列表與auto_ptr的

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

其中c ompiler?對我來說編譯得很好(gcc 4.6.1)。 –

+0

MinGW的-32 4.4,嗯,我不知道爲什麼出現這種情況 – oggmonster

+0

GCC 4.5.2不能編譯,給出了同樣的錯誤 – higuaro

回答

1

因爲std::auto_ptr沒有合適的拷貝構造函數,這意味着你的類沒有合適的拷貝構造函數,這意味着它不能由臨時構造 - 這就是你正在做的事情。

只是垃圾auto_ptr和移動到unique_ptr

+0

是,使一個很大的意義,將不得不等待C++ 11 :-( – oggmonster

+0

@oggmonster你什麼意思是等待?C++ 11已經在這裏了,編譯你的程序時只需使用'-std = C++ 0x'標誌。 –

1

試試這個:

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

好像std::auto_ptr沒有你的平臺上拷貝構造函數,所以它必須構造器的身體之前被初始化。

+0

還是輸出海合會相同的錯誤4.5.2 – higuaro

0

此外,你應該避免使用初始化列表如下:

{ 0, new MyObject() } 

相反,使用構造函數:

ItemBad(0, new MyObject()) 

例如,MSVC編譯器爲你的「好」的變體產生的錯誤,以及至於「壞」的一個:只要你的班級有一個Ctor,你必須使用它,而不是初始化列表。

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編譯器生成的拷貝costructor被調用以填補陣列插槽每ItemGood,這裏沒問題

ItemBad類聲明包含成員變量std::auto_ptr<MyObject> AutoObject,正如在另一個答案中指出的那樣,std::auto_ptr沒有copy-constructor,所以compil呃無法創建編譯器生成的複製構造函數ItemBad。當應用前面的邏輯,我們得到了相同的表達式替換與ItemGood

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

但在這裏我們沒有拷貝構造函數,所以您所報告的錯誤發生時,使用初始化列表中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