8

Visual Studio 2010 と C++ で奇妙な動作が発生しています。いくつかのグローバル定数を宣言するヘッダー ファイルがあります。

#ifndef CONSTANTS_H
#define CONSTANTS_H

#define WIN32_LEAN_AND_MEAN

// Macros...
#define SAFE_RELEASE(ptr) { if (ptr) { ptr->Release(); ptr = NULL } }
#define SAFE_DELETE(ptr) { if (ptr) { delete ptr; ptr = NULL; } }

// Constants...
const char* CLASS_NAME = "WinMain";
const char GAME_TITLE[] = "DirectX Window";

const int GAME_WIDTH = 640;
const int GAME_HEIGHT = 480;

#endif

私の問題は次の行にあります。

const char* CLASS_NAME = "WinMain";

このような状況でソリューションをビルドすると、次の 2 つのエラーが発生します。

error LNK1169: one or more multiply defined symbols found、 と

error LNK2005: "char const * const CLASS_NAME" (?CLASS_NAME@@3PBDB) already defined in graphics.obj

「ファイル内の検索」を実行したため、今は奇妙です。私は間違いなく他の場所で宣言していません。つまり、重複した宣言はありません。

次のように変更する必要があります。

const char* const CLASS_NAME = "WinMain";

また

const char CLASS_NAME[] = "WinMain";

それはうまくコンパイルされます!しかし、私が知る限り、char* xは と同等char x[]であり、ポインターとポイント先の値の両方に「const-ness」を適用しているという事実は違いがないはずです....それともそうですか?

私は Windows プラットフォームでの C++ 開発に少し慣れていないので、どんな助けでも大歓迎です!

4

3 に答える 3

7

あなたの間違いは、定数を定数として宣言しなかったことです。C++ 構文 (および C) では、定数ポインターを宣言するために、これを行う必要があります。

const char* const CLASS_NAME = "WinMain";

とは定数として正しく宣言されていることGAME_TITLEに注意してください。そのため、問題はありません。のみが正しく宣言されていません。つまり、非定数です。GAME_WIDTHGAME_HEIGHTCLASS_NAME

C++ の定数には、既定で内部リンケージがあります。これが、1 つの定義規則に違反することなく、ヘッダー ファイルで定数を定義できる理由です。

于 2012-12-07T23:35:33.497 に答える
5

ヘッダーで変数を定義しないでください。そのヘッダーを複数の翻訳単位に含めると、定義のコピーが複数になります。

そこでのみ変数を宣言しextern(を使用)、正確に 1 つの翻訳単位で定義します。

とは言うものの...組み込み型の定数にはデフォルトで内部リンケージがあるため、この規則の例外を作成できます。

つまり、2 つのプログラムは機能的に同一です。

const int x = 42;
int main() {}

static const int x = 42;
int main() {}

これにより、翻訳単位ごとに 1 つのコピーが生成され、問題が完全に回避されます。

配列も同じだと思います。だから、確かに、constそれを上げて、自分をノックアウトしてください。


しかし、私が知る限り、'char* x' は 'char x[]' と同等です。

関数パラメーター リスト内のみ。本格的な宣言でxは、初期化子から決定された次元を持つ配列型を取ります。

于 2012-12-07T22:52:10.950 に答える
1

ファイルを複数のコンパイル ユニットに含めると、各ユニットでその名前の変数を宣言するため、エラーが発生します。コンパイルは問題ではありませんが、リンカがリンクしようとすると、同じ変数の複数の定義が表示されます。const int変数には静的リンケージがあるため、これを回避できますconst char GAME_TITLE[]が、文字列リテラル (基本的にはchar配列) の場合、このエラーが発生します。を使用して問題を解決できるはずですextern

于 2012-12-07T22:52:42.437 に答える