2009-01-20 21 views
40

我已經看到了這兩種風格的代碼,我不確定一個是否比另一個更好(它只是一個風格問題)?你有什麼建議,你爲什麼會選擇一個在另一個。在C++中定義類字符串常量?

//Example1 
class Test { 

    private: 
     static const char* const str; 

}; 

const char* const Test::str = "mystr"; 

//Example2 
class Test { 

    private: 
     static const std::string str; 

}; 

const std::string Test::str ="mystr"; 
+1

這是怎麼令人不安? – 2012-12-30 10:21:43

回答

55

通常,您應該優先使用plain99指針的std::string。然而,在這裏,用字符串字面值初始化的char指針具有顯着的優點。

靜態數據有兩種初始化。一個稱爲靜態初始化,另一個稱爲動態初始化。對於那些用常量表達式初始化並且是POD(如指針)的對象,C++要求它們的初始化在動態初始化發生之前就開始了。初始化這樣一個std :: string將會動態完成。

如果在某個文件中有一個類的對象是一個靜態對象,並且需要在初始化過程中訪問該字符串,則可以依賴於在使用const char* const版本時已經設置的對象,而使用未被靜態初始化的std::string版本,您不知道該字符串是否已經被初始化 - 因爲跨轉換單元邊界的對象初始化順序未定義。

4

嗯,std :: string與const char *不同。我通常會在使用std :: string的時候犯錯,因爲它是一個具有許多附加功能的類,使它更容易使用。

如果性能至關重要,並且您使用const char *來提高效率,那就這樣吧。

2

第一個示例需要較少的管理字符串的開銷(即只是指向TEXT節的指針)。此外,第二種方法也可能需要堆分配以將字符串文字複製到std:string類緩衝區。所以,你最終會得到兩份數據。

1

第二個版本的優點是它帶有一個預先計算的長度和一個充實的字符串類的其他好處。第一個優點是唯一的初始化只是將一個指針指向已經加載到可執行映像中的靜態數據,其中第二個必須從同一個指針初始化字符串。

+0

第一個版本有strlen ... – 2009-01-20 02:30:42

+0

是的,但它是O(n)操作,因此根據使用情況而定,這可能是一個問題。 – Eclipse 2009-01-20 02:33:09

+0

但我想這只是一個關於std :: string vs char *的好處的爭論。 – Eclipse 2009-01-20 02:34:21

3

我傾向於贊成std :: string在執行C++時對char *的支持。我更喜歡std :: string主要是因爲它的內置功能以及無需處理指針的便利性和安全性。

但是,正如其他人所提到的,如果您過度關注性能,const char *版本可能會更好。我似乎記得有人聰明地說過早優化是所有邪惡(或某些這樣的)的根源。 :)

2

在涉及多個平臺的大型項目中,使用不同的編譯器和庫,許多團隊以及很多人都反覆遇到了使用靜態std :: strings的問題。在某些平臺上,std:string實現不是線程安全的。在一個平臺上,編譯器優化代碼跳過了從全局靜態常量初始化本地std:string的過程。在追查這些問題中的一些之後,我們只允許全局靜態常量用於內置類型。

1

首先,如果不會使用char *。如果你想要一個ASCIIZ字符串,定義它們直接之一:

const char Test::str[] = "mystr";

在大多數情況下,這就是我想要的使用。爲什麼浪費時間和內存來處理字符串類的開銷。請注意,「sizeof(Test :: str)」將準確地給出數組的長度,這是字符串的長度,包括終止NUL(strlen(str)+1)。