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