
C++初心者です。
constメンバ変数の初期化について教えてください。
クラスの中に、static constメンバ変数(配列)を持ちたいのですが、
<コード1>
class hoge {
public :
hoge(){};
virtual ~hoge(){};
static const int fuga[2] = {1, 2};
};
とすると、VC++ 2005では、
error C2059: 構文エラー : '{'
error C2334: '{' の前に予期しないトークンがありました。関数の本体は無視されます
というエラーが発生します。
何がいけないのでしょうか?
また、下の様にするとOKでした。
<コード2>
class hoge {
public :
hoge(){};
virtual ~hoge(){};
static const int fuga[2];
};
const int hoge::fuga[2] = {1,2};
こうすればコンパイルが通る事は分かったのですが、なぜこんな面倒な事をしないといけないのかが分かりません。
コード1では何がいけないのでしょうか?
以上、よろしくお願いします。
No.3ベストアンサー
- 回答日時:
> なぜこんな面倒な事をしないといけないのかが分かりません。
配列の実体の定義をひとつにするためです。
C++言語はC言語のスーパーセットですから、C言語とほぼ同様の特性を持っています。
この問題はC言語の知識があれば直感的に理解できるでしょう。
類似コードをC言語で書くと以下のようになります。
(もう、C言語は自信ないですが・・・)
[hoge.h]
typedef struct tagHoge { /* メンバ */ } Hoge;
extern const int hoge_fuga[];
void hoge_initialize(Hoge*);
void hoge_finalize(Hoge*);
[EOF]
[hoge.c]
const int hoge_fuga[] = {1, 2};
void hoge_initialize(Hoge*) {}
void hoge_finalize(Hoge*) {}
[EOF]
このコードは、extern で hoge_fuga という配列を外部参照し、
hoge.c ファイル中でその実態を定義するという単純なコードです。
hoge.c 以外のソースファイルで hoge_fuga の実体を定義すると多重定義でリンクエラーが起きてしまいます。
ですので、hoge.h をインクルードすることで外部参照宣言のみを行います。
もし質問者さんの最初のコードでコンパイルが通るとした場合、
hoge::fuga の実体は複数のソースファイルで定義されてしまう可能性が出てしまいますので、
その場合はC言語と同様にリンクエラーとなってしまうでしょう。
それならば、コンパイルも通さないほうが親切です。
ということで、最初のコードは通らないように規格が制定されたのでしょう。
なぜ、リンクエラーを起こすようになっているのかは、処理が複雑になり過ぎるためです。
コンパイル・リンク時間の増大やコンパイラ・リンカの不具合など、デメリットが大きすぎるんですね。
ちなみに、整数定数などは宣言と定義を同時にできますが、
これはサイズが小さく実体を複数作っても問題がないため、インライン展開や多重定義自体を許可することで実現しています。
なるほど。
ありがとうございます。
頂いた回答を見ていて、また疑問に思う事がありましたので、ちょっと試してみて、それから改めて質問したいと思います。
ありがとうございました。
No.2
- 回答日時:
まあ、私もよくはわからないけど、
通常のメンバ変数もクラスの定義内では初期化できないから。
恐らく同じ原理なのではないですか。
・・・多分。
ありがとうございます。
でも、static型なので、
>通常のメンバ変数もクラスの定義内では初期化できないから。
>恐らく同じ原理なのではないですか。
という訳ではなさそうです。
No.1
- 回答日時:
# 動作は仕様通り、(少なくとも現行仕様の範囲では)そういうものです>C++
> コード1では何がいけないのでしょうか?
言語仕様にそれを許可する記述がないから。
> こうすればコンパイルが通る事は分かったのですが、
> なぜこんな面倒な事をしないといけないのかが分かりません。
そういう言語仕様だから、ですかね。
ISO/IEC14882:2003 9.4.2 Static data membersあたりをご覧ください。
元々、整数定数などが宣言と定義を一緒にできるのは、
利便性のために、明示的にそれを許可する規定が盛り込まれたためです。
配列はここに規定されてません(許可されてるものの方が少ないです)。
# そもそも言語仕様Fix前のVC6みたいな古いコンパイラは、整数でも通らない…。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C++プログラミングコードにポリモーフィズムを取り入れ方を教えてください。 2 2023/06/09 11:17
- JavaScript javascriptで文字分割は、 split() などメソッド不要??? 4 2023/02/06 22:50
- C言語・C++・C# プログラミングのペーパーテスト 実行結果を表示せよ #include <stdio.h> int h 1 2022/07/09 15:27
- Java Java プログラム public class Main { public static void 3 2023/08/10 23:46
- C言語・C++・C# const char** p;のとき、free(p)でC4090エラーとなるのはなぜですか 3 2023/03/31 16:28
- JavaScript フォームが空欄の時にフォームの外をクリックすると、エラーが出るコードを調べています。 1 2023/06/25 11:51
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- Java java 入力 3 4 3 出力 ABC DEFG HIJ このようなプログラムの書き方を教えてくだ 2 2022/07/15 14:18
- Visual Basic(VBA) VBAでの共有パスにつきまして 1 2023/03/04 17:24
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ボタンをクリックすると数が増...
-
Boolean型配列中のTrueの有無を...
-
Vb.netのグローバル変数の宣言...
-
HTTPSのとき":"が"%3A"ではなく...
-
自動でリンクを実行する
-
-(ハイフン)_(アンダーバー)の...
-
ファイルの命名規則が決まって...
-
JavaScript window.openで開く...
-
google apps scriptの終了のさせ方
-
$("body").height();と$("body"...
-
同じIDで定義した要素の配列を...
-
Latexに関する質問です。
-
JavaScriptからPHPに配列を渡す...
-
C#で、ContextMenuStripに動的...
-
XMLHttpRequestでキャッシュを...
-
クリックすると上に開くアコー...
-
undefinedを表示させない方法は...
-
C# 演算 奇数と偶数 表現の仕方
-
毎日日付の変わるタイミングを...
-
ブックマークレットの() 背景...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Boolean型配列中のTrueの有無を...
-
HTTPSのとき":"が"%3A"ではなく...
-
ボタンをクリックすると数が増...
-
Linux バイナリ実行できない "...
-
ASP+アクセスでのSQLコメントに...
-
Excel VBA の ChangeFileAccess
-
アンカーリンクをクリックさせ...
-
javascriptで文字挿入でtoggle...
-
ifreamをリロードしたい
-
static と externについて
-
同じ型【ハイフンと数字】だけ...
-
【正規表現】【javascript】CR...
-
System::Drawing::Color::XXXX...
-
MFCのキャプション変更
-
VB.NETで変数の型は自作...
-
【Jquery】changeイベント毎にa...
-
サブウインドウから親ウインド...
-
Vb.netのグローバル変数の宣言...
-
window.onloadでのfunction
-
hogehogeの由来
おすすめ情報