簡體   English   中英

在C ++中定義常量C字符串的正確方法?

[英]Correct way to define a constant C-string in C++?

大多數時候我看到常量C字符串定義為:

static char const* MY_CONSTANT = "Hello World";

但是, 指針本身不是const 像下面這樣做是不是更合適?

static char const* const MY_CONSTANT = "Hello World";

我認為有兩個像這樣的常量全局變量的目標:

  1. 不允許修改字符串
  2. 不要讓變量指向其他任何東西

我只是假設在定義常量字符串時需要這兩個目標。

另一個有趣的事情是我被允許這樣做:

int main()
{
    auto MY_CONSTANT = "";
    MY_CONSTANT = "Another String";
}

這告訴我auto將字符串推斷為char const*而不是char const* const

所以我有兩個主要問題:

  1. 定義常量c風格字符串的最合適方法是什么(我認為常量指針指向某事,是更普遍的問題?)。 為什么選擇其中一個?
  2. 關於我使用auto例子,為什么它選擇char const*是有道理的(因為它是恆定的數據數組,而不是指針本身)。 我可以auto推導為char const* const還是可以更改代碼使其成為這樣的類型?

好吧,如果它真的是一個常數,那么constexpr將是C ++ 11的方法:

constexpr char const* MY_CONSTANT = "Hello World";

第一個例子:

static char const* MY_CONSTANT = "Hello World";

只是說我有一個指向具有靜態存儲持續時間的char const的指針,如果它在函數之外會使它成為全局。

如果我們要求指針也是const,那么我們需要你介紹的第二種形式。 這一切都取決於指針是否確實應該是const。 在大多數情況下,你看到沒有頂級const的代碼的原因是因為他們只是忘了把它放入,因為它們並不意味着指針也是const。

例如, static是否需要const成員是每個實例還是每個類:

class A
{
        char const* const const_per_instance = "Other Const String";
    public:
        constexpr static char const* const const_per_class = "Hello World" ;
};

如果我們要求const是每個類,那么我們需要使用靜態,否則不需要。 如果您不允許使用constexpr ,示例會略有變化:

class A
{
        char const* const const_per_instance = "Other Const String";
    public:
        static char const* const const_per_class  ;
};

char const* const A::const_per_class = "Hello World" ;

但實質是相同的只是語法不同。

對於你的第二個問題,因為Gotw#92表示自動降低頂級const,給出的一個例子如下:

const int   ci  = val;  
auto        g   = ci;

它說:

g的類型是int。

請記住,僅僅因為ci是const(只讀)與我們是否希望g為const無關。 這是一個單獨的變量。 如果我們想要g為const,我們就像上面的情況c那樣說過const auto

正在提到的例子如下:

int         val = 0;  
//..
const auto  c   = val;
constexpr auto& MY_CONSTANT = "Hello World";
  • MY_CONSTANT的類型為const char (&)[12]
  • 沒有衰減(數組綁定不會丟失)
  • 一切都是不變的 - 數組本身和引用(根據定義)
  • 一切都是constexpr(可以在編譯時使用) - 數組本身和引用
  • 由於constexpr ,MY_CONSTANT具有內部鏈接,可以在標題中使用

這是一種罕見的情況,你碰巧覆蓋指向const值的指針,因此大多數開發人員省略了第二個const,但在語義上它確實是這樣的:

static char const* const MY_CONSTANT = "Hello World";

或以這種形式:

static const char* const MY_CONSTANT = "Hello World";

如果它是另一個constexpr函數的一部分,則需要constexpr用於聲明:

static constexpr const char* const MY_CONSTANT = "Hello World";
static constexpr const char* Foo()
{
    // ...
    return MY_CONSTANT;
}

做得好,注意指針部分的常量! 很多人都沒有意識到這一點。

為了防止字符串文字被每個翻譯單元復制(或使優化器的字符串池部分更容易),我建議將實際數據放在某個源文件中。 如果更改文本,這也將節省一些重新編譯。

標題:

extern const char *const mystring;

資源:

extern const char *const mystring = "hello";

另外

標題:

extern const std::string mystring;

資源:

extern std::string mystring = "hello";

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM