7

my_test.h

#ifndef MY_TEST  
#define MY_TEST

struct obj {
  int x;
  int y;
};

class A {
private:
  const static int a=100;
  const static obj b;
};

const obj A::b={1,2};

#endif

このヘッダー ファイルを使用して cpp をコンパイルすると、エラー'multiple definition of 'A::b'が発生します。

  1. すでにガード マクロを使用しているのに、これはなぜですか?
  2. エラーが発生しないのはなぜA::aですか?(私は にコードconst static obj b={1,2}を書くことができませんclass A)
4

4 に答える 4

4

すでにガード マクロを使用しているのに、これはなぜですか?

ヘッダー ガードは、ヘッダー ファイルの内容が複数の翻訳単位にまたがってではなく、同じ翻訳単位に複数回含まれることを防ぐだけです。

にエラー メッセージが表示されないのはなぜですか (コードを にA::a書き込めません) 。const static obj b={1,2}class A

クラス内の初期化は、const リテラル型の静的データ メンバーの特殊なケースとして、コンパイラによって許可されます。あなたの例は、クラス内の初期化です。

const A::bヘッダーが含まれる各翻訳単位で同じシンボル名を定義するため、1 つの定義規則に違反します。

一度だけ定義されるように、定義を唯一のソース cpp ファイルに移動する必要があります。

于 2013-02-22T09:12:07.247 に答える
1

Alok はすでにあなたの質問に答えていますが、覚えやすい形でいくつかの簡単な経験則を以下に示します。

  1. 宣言は .h ファイルに入れます
  2. 定義は .cpp ファイルに入れます

したがって、静的メンバーは .h ファイルで宣言してから、.cpp ファイルで定義する必要があります。あなたの場合、宣言の構文を修正してから、それらを「my_test.cpp」ファイルに移動します。

于 2013-02-22T09:21:30.883 に答える
0

問題は、あなたの定義にA::bタイプが含まれていないことです。有効な定義であるためには、次のようにする必要があります。

const obj A::b = {1, 2};

これによりコンパイル エラーは解消されますが、このヘッダーを複数のソース ファイルにインクルードA::bすると、複数定義されるため、リンカー エラーが発生します。定義を .cpp ファイルに移動する必要があります。

于 2013-02-22T09:09:02.497 に答える
0

ヘッダー ガードがあるかどうかに関係なく、その初期化をヘッダー ファイルに配置すると、A::bそのヘッダー ファイルを含むすべてのソース ファイルで のインスタンスを取得することになります。したがって、リンカーエラー。

したがって、一般的に言えば、それは可能ですが、良い考えではありません。

于 2013-02-22T09:11:48.750 に答える