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


129

簡単に言えば:

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

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

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

    ...

    test();
};

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

私はC ++が初めてなので、気楽にやってください。なぜこれができないのですか?

回答:


145

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

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

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

unsigned char test::X = 4;

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


4
あなたは、ヘッダのみのライブラリを書いている場合は、CPPファイルを避けるために、この技術を使用することができます。stackoverflow.com/questions/11709859/...
Shitalシャー

62

クラス宣言の静的データメンバー宣言は、それらの定義ではありません。それらを定義するには、.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.
}

なぜここで.CPPにあるのかは、「unsigned char test :: X = 1;」です 「test :: X = 1;」の代わりに?静的変数Xは既に定義されていますが、なぜまだ「unsigned char」が必要ですか?@sergtk
ペニー

@Penny「test :: X = 1;」だから 割り当てとして解釈されますが、私たちがやろうとしているのは定義です。
Anonymous1847

4

これは一般に「静的constメンバーを持つ未解決のエクスターナル」を検索したときに出てきた最初のSOスレッドなので、未解決のエクスターナルの問題を解決するためのヒントをここに残しておきます。

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


2

私の場合、私は.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はなくなりました。


0

私の場合、間違ったリンクを使用していました。
これはc ++(cli)で管理されていましたが、ネイティブエクスポートを使用していました。リンカー->入力->アセンブリリンクリソースに、関数のエクスポート元のライブラリのDLLを追加しました。しかし、ネイティブc ++リンクでは、cppの実装を正しく「参照」するために.libファイルが必要であるため、.libファイルをリンカー->入力->追加の依存関係に追加するのに役立ちました。
[通常、マネージコードはdllのエクスポートとインポートを使用せず、参照を使用しますが、それは独特の状況でした。]

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.