静的クラスメンバーの未解決の外部シンボル
質問
非常に単純に:
ほとんどが静的パブリックメンバーで構成されるクラスがあるため、他のクラス/関数から呼び出す必要がある類似の関数をグループ化できます。
とにかく、クラスパブリックスコープで2つの静的なunsigned char変数を定義しましたが、同じクラスのコンストラクターでこれらの値を変更しようとすると、「未解決の外部シンボル」が表示されます。コンパイル時のエラー。
class test
{
public:
static unsigned char X;
static unsigned char Y;
...
test();
};
test::test()
{
X = 1;
Y = 2;
}
私はC ++を初めて使用するので、簡単に説明してください。なぜこれができないのですか?
解決
XとYの宣言に一致する定義を追加するのを忘れた
unsigned char test::X;
unsigned char test::Y;
どこか。静的メンバーを初期化することもできます
unsigned char test::X = 4;
また、宣言(通常は.Hファイル)ではなく、定義(通常はCXXファイル)で行います
他のヒント
クラス宣言内の静的データメンバーの宣言は、それらの定義ではありません。
それらを定義するには、 .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.
}
「静的constメンバーを持つ未解決の外部」を検索すると、これが最初のSOスレッドであるため、一般に、未解決の外部に関する1つの問題を解決するためのヒントをここに残します。
私にとって忘れていたのは、クラス定義 __ declspec(dllexport)
をマークすることであり、別のクラス(そのクラスのdllの境界外)から呼び出されたとき、もちろん私の未解決の外部エラー。
それでも、内部ヘルパークラスを他の場所からアクセス可能なクラスに変更するときは忘れやすいので、動的にリンクされたプロジェクトで作業している場合は、それも確認してください。
私の場合、.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はなくなりました。