2010-01-29 50 views
2

常常看到以下結構,特別是在構造串refrence:字符數組指針VS在PARAMS

class::class(const string &filename) 
{ 
} 


class::class(const char * const filename) 
{ 
} 

通過一步一步的調試,我發現了第二構造函數被始終稱爲如果我通過一個硬編碼的字符串。

任何想法:

1)爲什麼使用雙重結構?

2)什麼是速度差?

謝謝。

回答

3

需要兩個構造函數,因爲您可以將NULL傳遞給您的MyClass::MyClass(const std::string &arg)。提供第二個構造函數可以幫助您避免愚蠢的崩潰。

例如,您爲您的班級編寫構造函數,並使其成爲const std::string &,這樣如果您使用const char*,則不必檢查任何指針是否有效。 在你的代碼中的任何地方,你只是使用std::string s。在某個時候,你(或另一個程序員)通過那裏const char*。這裏有std::string - 它有一個構造函數,它需要char*,這非常好,除了事實,std::string a_string(NULL)編譯沒有任何問題,只是不起作用。

這就是像你出的第二構造函數來得心應手:

MyClass::MyClass(const char* arg) 
    : m_string(arg ? arg : "") 
{} 

,它將使一個有效std::string對象,如果你傳遞一個NULL

在這種情況下,我不認爲你需要擔心任何速度。你可以嘗試測量,雖然恐怕你會驚訝於如果沒有什麼差別(如果有)。

編輯:剛剛試過std::string a_string(NULL);,編譯就好了,以下是在我的機器上運行時發生了什麼(OS X + gcc 4.2.1)(我記得前段時間我在Windows上試過,結果是非常類似,如果不完全相同):

std::logic_error: basic_string::_S_construct NULL not valid

+0

謝謝,這澄清了這件事! – SyBer 2010-01-31 09:41:22

0

1)爲什麼使用雙重結構?如果的std :: string對象是因爲有從一個std的隱式轉換::串到一個const char const的被方便地用作parametersm

字符串參考版本是必需的。 const char * const版本是可選的,因爲字符數組可以隱式轉換爲std :: strings,但效率更高,因爲不需要創建臨時std :: string。

2) What is the speed difference? 

您需要自己測量一下。

0

它們基本上爲了方便而提供。有時候,如果你調用C函數,你會得到char *指針。其他人,你會得到字符串,所以提供這兩個構造函數對調用者來說只是一個方便。至於速度,兩者實際上具有相同的速度,因爲它們都向構造函數發送內存地址。

+0

相同的速度?即使採用字符串的構造函數確實與遠程存儲庫聯繫並通過Google存儲庫通過Google翻譯API下載了War和Peace的中文翻譯,並且char *構造函數只是賦值了一個值? :P – 2010-01-29 22:40:03

+0

如果原始字符串是C++字符串,則性能將相同。如果原始字符串是C風格的字符串(或文字),那麼只有std :: string版本將需要創建一個臨時的。我的建議是在必要時使用C++字符串,但如果您發現性能瓶頸,請考慮添加額外的C風格過載。 – 2010-01-29 23:13:38

1

如果實現自己處理const char*秒,那麼這很有用,但主要由std::string用戶調用。這些可以使用std::string API進行調用,該API通常只調用c_str()並分派到const char*實現。另一方面,如果調用者已經有一個C字符串,則不需要構造臨時或不需要的std::string(這可能是昂貴的,對於較長的字符串它是一個堆分配)。

另外,我曾經用它來解決以下情況:

我的界面了std::string的,但有一個外部模塊中實現,因此,這兩個模塊和調用模塊的STL二進制版本必須匹配,確切地說是,否則它會崩潰(對於便攜式庫不太好)。所以我改變了實際的界面使用const char*,並增加std::string重載,我宣稱inline,所以他們沒有出口。它沒有破壞現有的代碼,但解決了我所有的模塊邊界問題。