web-dev-qa-db-ja.com

静的クラスメンバーの未解決の外部シンボル

非常に簡単に言えば:

ほとんどが静的なパブリックメンバーで構成されるクラスを持っているので、他のクラス/関数から呼び出す必要がある類似の関数をグループ化できます。

とにかく、クラスパブリックスコープで2つの静的なunsigned char変数を定義しました。同じクラスのコンストラクターでこれらの値を変更しようとすると、コンパイル時に「未解決の外部シンボル」エラーが発生します。

class test 
{
public:
    static unsigned char X;
    static unsigned char Y;

    ...

    test();
};

test::test() 
{
    X = 1;
    Y = 2;
}

私はC++を初めて使用するので、簡単です。なぜこれができないのですか?

121
Daniel

XとYの宣言に一致する定義を追加するのを忘れた

unsigned char test::X;
unsigned char test::Y;

どこかに。静的メンバーも初期化することもできます

unsigned char test::X = 4;

繰り返しますが、宣言(通常は.Hファイル)ではなく、定義(通常はCXXファイル)で行います。

134
Colin Jensen

クラス宣言内の静的データメンバーの宣言は、それらの定義ではありません。それらを定義するには、.CPPファイルでこれを行い、シンボルの重複を避けます。

宣言および定義できるデータは、整数の静的定数のみです。 (enumsの値は定数値としても使用できます)

コードを次のように書き直すことができます。

class test {
public:
  const static unsigned char X = 1;
  const static unsigned char Y = 2;
  ...
  test();
};

test::test() {
}

静的変数を変更できるようにしたい場合(つまり、constとして宣言するのが不適切な場合)、次の方法で.H.CPPの間でコードを分離できます。

.H:

class test {
public:

  static unsigned char X;
  static unsigned char Y;

  ...

  test();
};

.CPP:

unsigned char test::X = 1;
unsigned char test::Y = 2;

test::test()
{
  // constructor is empty.
  // We don't initialize static data member here, 
  // because static data initialization will happen on every constructor call.
}
60
sergtk

これは一般に「静的constメンバーを持つ未解決の外部」を検索するときに出てくると思われる最初のSOスレッドなので、ここでは未解決の外部に関する1つの問題を解決するための別のヒントを残します:

私にとって忘れていたのは、クラス定義__declspec(dllexport)をマークすることであり、別のクラス(そのクラスのdllの境界外)から呼び出されたとき、もちろん、未解決の外部エラーが発生しました。
それでも、内部ヘルパークラスを他の場所からアクセスできるクラスに変更するときは忘れやすいので、動的にリンクされたプロジェクトで作業している場合は、それも確認してください。

3

私の場合、.hファイルで1つの静的変数を宣言しました。

//myClass.h
class myClass
{
static int m_nMyVar;
static void myFunc();
}

myClass.cppで、このm_nMyVarを使用しようとしました。次のようなLINKエラーが発生しました。

エラーLNK2001:未解決の外部シンボル「public:static class ...リンクエラー関連のcppファイルは次のようになります。

//myClass.cpp
void myClass::myFunc()
{
myClass::m_nMyVar = 123; //I tried to use this m_nMyVar here and got link error
}

そこで、myClass.cppの上に以下のコードを追加します

//myClass.cpp
int myClass::m_nMyVar; //it seems redefine m_nMyVar, but it works well
void myClass::myFunc()
{
myClass::m_nMyVar = 123; //I tried to use this m_nMyVar here and got link error
}

その後、LNK2001はなくなりました。

2
Penny