web-dev-qa-db-ja.com

クラス内の静的文字列定数と定数の名前空間[c ++]

プロジェクトで使用される文字列定数を宣言したいさまざまなクラス間。私は2つの選択肢を検討しています

オプション1:

#header file 
class constants{
    static const string const1;
};

#cpp file

const string constants::const1="blah";

オプション2:

#header file 
namespace constants{
    static const string const1="blah";
};

何がより良い実装になるのか疑問に思っています。

すでに見た

クラス固有の名前付き定数をC++で格納する場所

C++で定数文字列を配置する場所:静的クラスメンバーまたは匿名名前空間


更新:

オプション3:

「potatoswatter」と「sellibitze」からの提案に基づいて、私は現在次の実装を持っていますか?

#header file
namespace constants{
    extern const string& const1(); //WORKS WITHOUT THE EXTERN  ***WHY***
};

#cpp file
namespace constants{
   const string& const1(){static string* str = new string ("blah"); return *str;}
}

定数を使用する必要があるヘッダーファイルをインクルードしています。この実装の主な短所はありますか?

19
Asif Mohammed

2年後の更新:

複数のソースファイルからアクセスできるすべてのグローバルは、リンカーがファイル間でオブジェクトを共有し、プログラムが適切に初期化するように、inline関数でラップする必要があります。

inline std::string const &const1() {
    static std::string ret = "hello, world!";
    return ret;
}

inline関数は暗黙的にexternであり、必要に応じて名前空間またはクラスでラップできます。 (ただし、静的メンバーを保持するためだけにクラスを使用しないでください。名前空間の方が適しています。また、匿名の名前空間を使用しないでください。リンカーが無効になり、ソースごとに異なるstd::stringオブジェクトが表示されます。 )

11
Potatoswatter

std::stringに頼るすべての回答は、プログラム(およびバイナリ)の存続期間を通じて一定のままである文字列リテラルにメモリを動的に割り当てるリスクがあるため、避ける必要があります。

sellibitze の答えは近づいていますが、一度宣言してから他の場所で定義するという問題があります。これはエレガントではなく、より手間がかかります。最善の方法は

namespace constants {
    const char * const blah = "blah!"
    const char * const yada = "yada yada!"
}

これは解決策についてさらに説明します ここ

8
legends2k

どちらでもない。私はこれで行きます:

// header file
namespace constants {
extern const char const1[];
}

// cpp file
namespace constants {
extern const char const1[] = "blah";
}

ヘッダーファイルには、不完全な型のconst1の宣言が含まれていますが、char const*に変換可能であり、cppファイルには外部リンケージのある文字配列の定義が含まれています。 std::stringのような動的な初期化はありません。だから、それはプラスです、私見。

5
sellibitze

オプション1は、オプション2と同じことを実現しますが、より厄介な方法です。

特にグローバルアクセス/定数の場合、静的メンバーのみを持つクラスを使用する場合は、名前空間を使用します。

4