いつもお世話になっております
例えば、
class ABC
{
static const x = 100; // OK
static const y[/url] = {100,200,300}; // コンパイラエラー:{ が関数外に存在する。 云々
}
今回ちょうど配列(y[/url])のような定数シリーズを定義したいんで、どうすればいいのでしょうか
どうぞ宜しくお願いします。
class定数を定義したいですが
Re:class定数を定義したいですが
ご返答ありがとうございます。
書き直しますと下記のようになりますが
class ABC
{
private:
static const int x = 100; // OK
static const int y[/url] = {100,200,300}; // コンパイラエラー:{ が関数外に存在する。 云々
}
現象は変わりません。
なぜ xはOK, y[/url]はだめでしょうか。
実現方法ありますか
宜しくお願いいたします
書き直しますと下記のようになりますが
class ABC
{
private:
static const int x = 100; // OK
static const int y[/url] = {100,200,300}; // コンパイラエラー:{ が関数外に存在する。 云々
}
現象は変わりません。
なぜ xはOK, y[/url]はだめでしょうか。
実現方法ありますか
宜しくお願いいたします
Re:class定数を定義したいですが
Blue さんの通り、クラスの static メンバ変数はクラス定義の外(.cpp ファイル内)で初期化を行うのが普通です。
クラス内で初期化を行っている時、そのクラスが複数のソースからインクルードされている場合はリンカエラーが出ます。
(重複したシンボル名とか云々)
また、
> static const int y[/url] = {100,200,300}; // コンパイラエラー:{ が関数外に存在する。 云々
これがコンパイルエラーなのは、単にクラス内で配列を初期化できないから(仕様?)です。
クラス内の static メンバ変数の正しい初期化の仕方は以下のようになります。
初期化部分を別にする必要はなくなります。
クラス内で初期化を行っている時、そのクラスが複数のソースからインクルードされている場合はリンカエラーが出ます。
(重複したシンボル名とか云々)
また、
> static const int y[/url] = {100,200,300}; // コンパイラエラー:{ が関数外に存在する。 云々
これがコンパイルエラーなのは、単にクラス内で配列を初期化できないから(仕様?)です。
クラス内の static メンバ変数の正しい初期化の仕方は以下のようになります。
// ヘッダファイル内 class ABC { private: static const int x; static const int y[/url]; // ↑宣言のみ }; // cpp ソースファイル内(上記のヘッダをインクルードすること) const int ABC::x = 100; const int ABC::y[/url] = {100,200,300}; // ↑ static は不要ちなみに、配列を使わないクラス定数(かつ整数)なら enum を使用することで
初期化部分を別にする必要はなくなります。
Re:class定数を定義したいですが
> ちなみに、配列を使わないクラス定数(かつ整数)なら enum を使用することで
> 初期化部分を別にする必要はなくなります。
いわゆるenumハックという手法ですが、それは標準準拠度の処理系への対策です。
まともなコンパイラであれば、const修飾子が付いた汎整数型の静的メンバ変数は、クラス定義の際に初期化子を指定することができます。
> 初期化部分を別にする必要はなくなります。
いわゆるenumハックという手法ですが、それは標準準拠度の処理系への対策です。
まともなコンパイラであれば、const修飾子が付いた汎整数型の静的メンバ変数は、クラス定義の際に初期化子を指定することができます。
Re:class定数を定義したいですが
御津凪 さま、たかぎ さま
ご教授ありがとうございます。
やりかたはよく分かりました。
いま MS VC++ 2008 を使っています。
御津凪 さまが書かれました:
> そのクラスが複数のソースからインクルードされている場合はリンカエラーが出ます。
意味はよく分かりました。正しいと思います。
ただ、これだと、classというスコープの意義がなくなったような感じですね。
現にメンバー関数もクラスの中に定義していて、クラスが複数のソースからインクルードされていますが
関数の再定義エラーは出ませんでした。
なぜか、MS VC++ はメンバー関数と静的なメンバー変数に違う論理で取り扱われているようですね。
たかぎ さまが書かれました:
> const修飾子が付いた汎整数型の静的メンバ変数は、クラス定義の際に初期化子を指定することができます。
JAVA言語はこうなっています。
こうならないのはC++の仕様のせいか、それとも特定のC++のコンパイラーのせいでしょうか。
ご教授ありがとうございます。
やりかたはよく分かりました。
いま MS VC++ 2008 を使っています。
御津凪 さまが書かれました:
> そのクラスが複数のソースからインクルードされている場合はリンカエラーが出ます。
意味はよく分かりました。正しいと思います。
ただ、これだと、classというスコープの意義がなくなったような感じですね。
現にメンバー関数もクラスの中に定義していて、クラスが複数のソースからインクルードされていますが
関数の再定義エラーは出ませんでした。
なぜか、MS VC++ はメンバー関数と静的なメンバー変数に違う論理で取り扱われているようですね。
たかぎ さまが書かれました:
> const修飾子が付いた汎整数型の静的メンバ変数は、クラス定義の際に初期化子を指定することができます。
JAVA言語はこうなっています。
こうならないのはC++の仕様のせいか、それとも特定のC++のコンパイラーのせいでしょうか。