2016-11-08 69 views
2

In C++ in Plain English,Second Edition(1999),書中有一段說「=」可以用來在調用正確的構造函數時進行初始化。等給出一類CStr和構造CStr(char*),書中這樣說:爲什麼此C++成員初始值設定項列表不起作用?

同樣,最後宣言調用構造函數CStr的(字符*):

CStr name3 = "Jane Doe"; 

我想嘗試同與std::string構造函數的東西。我的測試代碼的部分是:

using namespace std; 
class CStr { 
private: 
    string name; 
public: 
    CStr(string s): name(s) {} 
}; 

int main() { 
    CStr name3 = "Jane Doe"; 
} 

當我編譯,但是,我得到的NAME3初始化錯誤:

「從‘爲const char [9]’非標轉換鍵入'CStr'請求「。

爲什麼不初始化CStr :: name爲字符串s =「Jane Doe」?像string nameTest{"Jane Doe"};這樣的字符串測試工作,所以我認爲這也會起作用。也許這本書的舊版(這是我現在唯一的書),但我認爲這個錯誤更多。

+2

順便說一句,自從99年以來C++發生了很大的變化。自那時起,兩項新標準添加了一堆新功能,並刪除了一些過時的標準。 –

+1

實際上,我的書桌上仍有該書的副本。非常有用的書可以作爲C標準庫的快速參考。 – user4581301

+1

順便說一下,你可以使用帶有'CStr(char *)'構造函數的字符串文字的時代已經過去了。字符串文字不能轉換爲'char *'類型,只能轉換爲'const char *'。 – AnT

回答

6

你的書很舊,但基本上正確[1]。請注意,"Jane Doe"不是std::string,它是const char[9](並可能衰減到const char*)。因此,對於CStr name3 = "Jane Doe";,需要兩個用戶定義的轉換(即,const char*std::stringstd::stringCStr),這在一個implicit conversion中是不允許的。

這也表明,如果CStr的構造以const char*作爲其參數,CStr name3 = "Jane Doe";可以正常工作,因爲只需要一個用戶定義的轉換。

你可以通過添加顯式轉換減少一個:

CStr name3 = std::string("Jane Doe"); 

,或者使用string literal(因爲C++ 14)直接,這是std::string類型:

CStr name3 = "Jane Doe"s; 

爲什麼沒有將CStr :: name初始化爲字符串s =「Jane Doe」?像string nameTest{"Jane Doe"};這樣的字符串測試工作,所以我認爲這也會起作用。

你提的問題不夠清楚,反正std::string nameTest{"Jane Doe"};作品,因爲(取決於你的誤解,)(1)只有一個隱式轉換(const char* - >std::string這裏需要;(2)string nameTest{"Jane Doe"};是直接初始化。

As @LightnessRacesinOrbit評論,direct initialization(ieCStr name3("Jane Doe")CStr name3{"Jane Doe"}(因爲C++ 11))將正常工作,而CStr name3 = "Jane Doe";copy initialization是,它們在某些點是不同的:

另外,在複製初始化的隱式轉換必須 產生Ť直接從初始化器,而例如 直接初始化期望從 初始值設定項到T的構造函數的參數的隱式轉換。

struct S { S(std::string) {} }; // implicitly convertible from std::string 
S s("abc"); // OK: conversion from const char[4] to std::string 
S s = "abc"; // Error: no conversion from const char[4] to S 
S s = "abc"s; // OK: conversion from std::string to S 

這意味着,對於一個複製的初始化,參數Jane Doe,這是一個const char*,必須被轉換到CStr直接;因爲需要兩次用戶定義的轉換,所以代碼被拒絕。對於直接初始化,可以將Jane Doeconst char*)轉換爲參數CStr的構造函數(即std::string),然後調用CStr::CStr(std::string)構造對象。


[1] "Jane Doe"是一個C語言風格string literal是常量,由C++ 11是非法的其分配給char*,例如

char * pc = "Jane Doe";   // illegal 
const char * pcc = "Jane Doe"; // fine 
+2

或者'CStr name3(「Jane Doe」)'或者'CStr name3 {「Jane Doe」}' –

+0

你的回答很好,但是這個難題的缺點是這是複製初始化與其他類型不同的一種方式。 –

+0

@LightnessRacesinOrbit OP的誤解對我來說還不夠清楚,無論如何,我試圖添加相關的解釋。 – songyuanyao

相關問題