C ++で静的定数を初期化する場所


129

クラスがあります

class foo {
public:
   foo();
   foo( int );
private:
   static const string s;
};

sソースファイルの文字列を初期化するのに最適な場所はどこですか?

回答:


178

1つのコンパイルユニット(通常は.cppファイル)のどこでも実行できます。

foo.h

class foo {
    static const string s; // Can never be initialized here.
    static const char* cs; // Same with C strings.

    static const int i = 3; // Integral types can be initialized here (*)...
    static const int j; //     ... OR in cpp.
};

foo.cpp

#include "foo.h"
const string foo::s = "foo string";
const char* foo::cs = "foo C string";
// No definition for i. (*)
const int foo::j = 4;

(*)整数定数式以外のコードで使用する場合は、標準に従ってi、クラス定義の外(jisなど)で定義する必要があります。詳細については、以下のDavidのコメントを参照してください。


27
私は賛成票を投じましたが、標準を確認した後、コードにエラーがあります。cppで定義するi必要があります。§9.4.2/ 4 静的データメンバーがconst整数型またはconst列挙型である場合、クラス定義での宣言により、定数定数式(5.19)となる定数初期化子を指定できます。その場合、メンバーは整数定数式で表すことができます。メンバーは、プログラムで使用され、ネームスペーススコープ定義に初期化子が含まれていない場合、ネームスペーススコープで定義されます。
デビッドロドリゲス-dribeas

3
標準からの引用に基づいて、整数定数式以外の場所で使用された場合にのみi定義する必要があるようですよね?この場合、確認するのに十分なコンテキストがないため、エラーがあるとは言えません。または、厳密に言うと、他のコードがない場合は上記の例が正しいです。今、私はあなたのコメントに感謝します(+1)、私はまだ自分で物事を学んでいます!だから私は答えでその点を明確にしようと思います、それが良いかどうか知らせてください...
squelart

@squelartばかげて聞こえたら申し訳ありませんが、整数定数式以外のステートメントの例は?
Saksham 2013

3
関数を呼び出すたとえば@Saksham、例えば:int f() { return 42; } class foo { static const int i = f(); /* Error! */ }注C ++ 11の「constexprの」関数を呼び出すことができますこと:constexpr int f() { return 42; } class foo { static const int i = f(); /* Ok */ }
squelart

@squelartメンバーを使用する場合は定義を指定する必要があるようにテキストを読みました。標準の表現では、その要件が整数定数式に限定されていません。
VladLosev 2013年

12

静的メンバーは、ファイルスコープの.cpp変換ユニットまたは適切な名前空間で初期化する必要があります。

const string foo::s( "my foo");

11

同じ名前空間内の翻訳単位で、通常は上部にあります。

// foo.h
struct foo
{
    static const std::string s;
};

// foo.cpp
const std::string foo::s = "thingadongdong"; // this is where it lives

// bar.h
namespace baz
{
    struct bar
    {
        static const float f;
    };
}

// bar.cpp
namespace baz
{
    const float bar::f = 3.1415926535;
}

8

C ++ 17以降、インライン指定子は変数にも適用されます。クラス定義で静的メンバー変数を定義できるようになりました。

#include <string>

class foo {
public:
   foo();
   foo( int );
private:
   inline static const std::string s { "foo" };
};

1

static const int ARRAYSIZEヘッダーファイルで初期化されるのは整数値(例:)のみです。これらは通常、配列のサイズなどを定義するためにクラスヘッダーで使用されるためです。非整数値は実装ファイルで初期化されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.