2017-08-04 77 views
3

我瞭解到,在C++中,功能樣式轉換與構造

typedef foo* mytype; 

(mytype) a  // C-style cast 

mytype(a)   // function-style cast 

做同樣的事情。

但我注意到函數式轉換與構造函數共享相同的語法。 是不是有不明確的情況下,我們不知道它是一個演員或建設者?

char s [] = "Hello"; 
std::string s2 = std::string(s);  // here it's a constructor but why wouldn't it be ... 
std::string s3 = (std::string) s; // ... interpreted as a function-style cast? 
+2

實際上,在您顯示的示例中*兩個*個案都會調用一個'std :: string'構造函數。 *相同*構造函數。 –

+0

注意:在C++中,你通常應該更喜歡明確的轉換static_cast,reinterpret_cast,const_cast,dynamic_cast,static_pointer_cast,reinterpret_pointer_cast,const_pointer_cast和dynamic_pointer_cast(以及move& '前鋒' - 是的,他們*只是在C風格演員陣容*上)。他們更容易在代碼中搜索,對於意圖和安全性更加明確(例如,最糟糕的C風格演員陣容是生成'reinterpret_cast',後面跟着'const_cast')。 –

回答

10

句法上,它是總是一個演員。該演員陣容可能恰好稱爲構造函數:

char s [] = "Hello"; 
// Function-style cast; internally calls std::basic_string<char>::basic_string(char const*, Allocator) 
std::string s2 = std::string(s); 
// C-style cast; internally calls std::basic_string<char>::basic_string(char const*, Allocator) 
std::string s3 = (std::string) s; 
0

編譯器知道。當兩種情況都有一個時,它會調用構造函數。

1

轉換是初始化的一種形式。當一個類型可以隱式轉換爲另一個類型時,函數類型轉換是一種直接初始化的形式。編譯器知道哪些類型是可轉換的。

只要有東西轉換爲類類型,就會使用目標類型的轉換構造函數或源類型的轉換運算符。在你的例子中,兩個cast都調用默認的構造函數。

+0

謝謝。好的,編譯器知道,但我怎麼知道哪些情況可以通過構造函數轉換,或者只是通過改變類型而不改變值(如c風格轉換)? – Basj

+0

@Basj'我怎麼能知道哪些情況是可轉換的?您可以使用'std :: is_convertible'來請求編譯器,或者您可以閱讀該類的定義(以及源對象的類的定義,如果適用),以查看類具有適當的轉換構造函數(或源對象具有適當的轉換運算符)。轉換爲類類型始終是對構造函數的調用。通過查看它的定義,你可以發現一個類型是否是一個類。 – user2079303

+0

「只要有東西被轉換爲類類型,就調用構造函數。」 - 不正確。轉換操作符可能會被調用。這並不一定會調用構造函數(它通常會,但它可能會通過引用返回緩存的對象)。 –