#include <iostream>
using namespace std;
class T1
{
const int t = 100;
public:
T1()
{
cout << "T1 constructor: " << t << endl;
}
};
Constメンバー変数t
を100で初期化しようとしていますが、次のエラーが発生します。
test.cpp:21: error: ISO C++ forbids initialization of member ‘t’
test.cpp:21: error: making ‘t’ static
const
値を初期化するにはどうすればいいですか?
const
変数は、変数が変更可能かどうかを指定します。割り当てられた定数値は、変数が参照されるたびに使用されます。割り当てられた値はプログラムの実行中に変更することはできません。
Bjarne Stroustrupの 説明 簡単に要約すると:
クラスは通常ヘッダーファイルで宣言され、ヘッダーファイルは通常多くの翻訳単位に含まれます。ただし、複雑なリンカ規則を避けるために、C++ではすべてのオブジェクトに一意の定義が必要です。 C++がオブジェクトとしてメモリに格納する必要があるエンティティのクラス内定義を許可した場合、その規則は破られるでしょう。
const
変数はクラス内で宣言する必要がありますが、その中で定義することはできません。クラスの外でconst変数を定義する必要があります。
T1() : t( 100 ){}
ここでの代入t = 100
は初期化子リストの中で、クラスの初期化が起こるずっと前に起こります。
まあ、あなたはそれをstatic
にすることができます:
static const int t = 100;
あるいは、メンバー初期化子を使うこともできます。
T1() : t(100)
{
// Other constructor stuff here
}
クラス内でconstメンバを初期化する方法はいくつかあります。
Constメンバの定義は一般的に、変数の初期化も必要です。
1)クラス内で、constを初期化したい場合、構文は次のようになります。
static const int a = 10; //at declaration
2)第二の方法はすることができます
class A
{
static const int a; //declaration
};
const int A::a = 10; //defining the static member outside the class
3)宣言時に初期化したくない場合は、もう1つの方法はコンストラクタを使用することです。変数は初期化リストで(コンストラクタの本体ではなく)初期化する必要があります。このようにする必要があります
class A
{
const int b;
A(int c) : b(c) {} //const member initialized in initialization list
};
C++ 11をサポートするようにコンパイラをアップグレードすれば、コードは完全に機能します。
コンストラクタで初期化リストを使用してください。
T1() : t( 100 )
{
}
const
データメンバをクラスstaticにしたくない場合は、クラスのコンストラクタを使用してconst
データメンバを初期化できます。例えば:
class Example{
const int x;
public:
Example(int n);
};
Example::Example(int n):x(n){
}
クラスに複数のconst
データメンバがある場合は、次の構文を使ってメンバを初期化できます。
Example::Example(int n, int z):x(n),someOtherConstVariable(z){}
別の解決策は
class T1
{
enum
{
t = 100
};
public:
T1();
};
そのため、tは100に初期化され、変更することはできず、非公開です。
メンバーが配列の場合、通常の値よりも少し複雑になります。
class C
{
static const int ARRAY[10];
public:
C() {}
};
const unsigned int C::ARRAY[10] = {0,1,2,3,4,5,6,7,8,9};
または
int* a = new int[N];
// fill a
class C {
const std::vector<int> v;
public:
C():v(a, a+N) {}
};
もう一つの可能な方法は名前空間です:
#include <iostream>
namespace mySpace {
static const int T = 100;
}
using namespace std;
class T1
{
public:
T1()
{
cout << "T1 constructor: " << mySpace::T << endl;
}
};
不利な点は、他のクラスがヘッダファイルを含んでいる場合、他のクラスもその定数を使用できることです。
このクラスメンバー変数の初期化を可能にするためにstatic
を追加できます。
static const int i = 100;
ただし、そのクラスからインスタンス化されたすべてのオブジェクトは、インスタンス化されたオブジェクトのスコープメモリ外の内部メモリに格納されている同じ静的変数を共有するため、内部クラス宣言を使用することは必ずしもお勧めできません。
これは正しい方法です。あなたはこのコードを試すことができます。
#include <iostream>
using namespace std;
class T1 {
const int t;
public:
T1():t(100) {
cout << "T1 constructor: " << t << endl;
}
};
int main() {
T1 obj;
return 0;
}
C++10 Compiler or below
を使用している場合は、宣言時にconsメンバーを初期化することはできません。そのため、ここではconstデータメンバを初期化するためのコンストラクタを作成する必要があります。また、メモリを即座に取得するには、イニシャライザリストT1():t(100)
を使用する必要があります。