全局const char上的错误LNK1169*

mne*_*nic 7 c++ visual-studio-2010 visual-c++

我在使用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
Run Code Online (Sandbox Code Playgroud)

我的问题来自以下行:

const char* CLASS_NAME = "WinMain";
Run Code Online (Sandbox Code Playgroud)

当它是这样的,我构建我的解决方案时,我得到以下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";
Run Code Online (Sandbox Code Playgroud)

要么

const char CLASS_NAME[] = "WinMain";
Run Code Online (Sandbox Code Playgroud)

它编译得很好!但据我所知char* x,相当于char x[],并且我在指针和指向值上强制执行'const-ness'这一事实应该没有区别......或者是这样吗?

我对Windows平台上的C++开发有点新意,所以任何帮助都将不胜感激!

AnT*_*AnT 6

你错了是你没有将常量声明为常量.在C++语法(以及C语言)中,为了声明一个常量指针,你必须这样做

const char* const CLASS_NAME = "WinMain";
Run Code Online (Sandbox Code Playgroud)

注意你的GAME_TITLE,GAME_WIDTH并且GAME_HEIGHT被正确地声明为常量,这就是为什么它们没有给你带来麻烦.只有CLASS_NAME声明不正确,即非常数.

默认情况下,C++中的常量具有内部链接,这就是为什么您可以在头文件中定义它们而不违反一个定义规则的原因.


Lig*_*ica 5

不要在标题中定义变量。当您在多个翻译单元中包含该标头时,您将获得该定义的多个副本。

仅在其中声明变量(使用extern),并以一个翻译单元精确地定义它们。

就是说……对于内置类型的常量,可以对此规则做一个例外,因为它们默认情况下具有内部链接。

也就是说,这两个程序在功能上是相同的:

const int x = 42;
int main() {}
Run Code Online (Sandbox Code Playgroud)

static const int x = 42;
int main() {}
Run Code Online (Sandbox Code Playgroud)

这样可以确保为每个翻译单元生成一份副本,从而完全避免了该问题。

认为数组也是如此。所以,可以肯定的是,const把自己踢了出去。


但据我所知'char * x'等同于'char x []',

仅在功能参数列表中。在完整的声明中,x将采用从初始化程序确定维度的数组类型。