2014-02-11 18 views
24

它爲什麼編譯?爲什麼我可以用指針賦值struct?

struct UE{ 
    UE(bool a = true) { }; 
// UE(){}; // if UE took no initial args and called below, gcc will complain. 
}; 
class VA { 
    protected: 
      UE ue; 
    public: 
      VA(); 
}; 
VA::VA() 
{ 
    ue = new UE(true); // ???why??? 
// ue = new UE(); // will complain 
} 

我試着用gcc(GCC)4.6.2。 如何分配一個指針結構?

+1

它編譯VS2010。 – herohuyongtao

+2

@herohuyongtao問題是爲什麼。答案是隱式轉換。 – juanchopanza

+1

@HenkHolterman'new'返回一個指針。 –

回答

29

您碰到了一個事實,即您沒有將您的構造函數標記爲explicit,因此它可用於隱式轉換。

new UE(true)返回一個指針。所有指針可隱式轉換爲bool,如果它們非空,則會產生trueUE可以隱含地從bool構建。因此實際上,由new返回的指針被轉換爲bool,該指針使用您的構造函數轉換爲UE,然後調用UE的複製賦值運算符。當然,由new分配的內存已被泄漏。

回收信息是:除非您確實希望它們可用於隱式轉換,否則始終將您的單參數構造函數標記爲explicit。通過「單參數構造函數」,我的意思是可以用一個參數來調用的構造函數。要麼因爲它有一個參數,要麼在第一個參數有默認參數後有更多參數和所有參數。

+2

謝謝,這解釋了一切。 – BetterWang

+0

我真的希望海灣合作委員會會爲此產生警告。它似乎應該與「你可能想要做的事」區分開來。 Cppcheck(1.63.1)沒有收到。 g ++ 4.7.2沒有抓住它。 –

+0

@ColinDBennett你的意思是因爲'new'?現代C++代碼無論如何都不會包含許多新的調用,所以它很少適用。與其他任何方式獲取的指針,這種轉換是公平的比賽,我會非常生氣,如果我打算,並得到一個警告。 – Angew

8

有從任何指針到bool的隱式轉換。因此,在將指針轉換爲bool值後,此代碼隱式地調用單參數構造函數值

解決此問題的一種方法是使單個參數構造函數顯式化。

struct UE{ 
    explicit UE(bool a = true) { }; 
}; 

這將防止代碼編譯,除非構造函數被顯式調用

1

任何標量類型可以被轉換成布爾值真或假根據其值是否等於零或不..

在這份聲明中

ue = new UE(true); 

的編譯器隱式拷貝賦值運算符定義被調用。由於表達式新的UE(真)不等於零,因此它可以隱式轉換爲布爾值true。類UE具有轉換構造器

UE(bool a = true); 

將bool類型的對象轉換爲UE類型的對象。

爲了防止這樣的用法應定義構造函數明確

explicit UE(bool a = true); 
1

如果您標記構造器的明確,這將不起作用:

explicit UE(bool a = true) { }; 

這是因爲從隱式轉換指針指向一個布爾值,我們可以看到這是由C++草案標準節允許4.12布爾轉換說(重點煤礦):

算術,無作用域枚舉的一個prvalue,指針,或指針構件類型可以轉換爲bool類型的prvalue。