2010-11-15 57 views
3

我在头文件中定义了下面的结构和结构对象,如下所示:为什么错误LINK2005:当我将对象声明为静态时,对象已定义的错误消失

struct STConfigurationDetails 
{ 
    bool bAutoStart; 
    bool bAutoLog; 
    bool bAutoScan; 
    bool bAutoMount; 
    bool bAutoOpen; 
    bool bAutoDetectLast; 
}; 

struct STConfigurationDetails g_objConfigurationDetails ; 

在头文件中,我自己拥有使用g_objConfigurationDetails的方法和方法体。当我将头文件包含到另一个cpp文件并调用该方法时,这工作正常。但是当我将头文件添加到另一个cpp文件时,我得到了错误:

Error 1 error LNK2005: "struct STConfigurationDetails g_objConfigurationDetails" ([email protected]@[email protected]@A) already defined in NDSClientDlg.obj NDSConnectDlg.obj NDSClient

Error 2 fatal error LNK1169: one or more multiply defined symbols found d:\FromClearCase\Development_view\NDS_11152010\exe\Debug\NDSClient.exe 1 NDSClient

在搜索了几个线程后,我发现我必须将我的对象声明为静态并且它已经解决了。但我想知道为什么在我只在te头文件中创建实例时出现多个实例错误。

这是因为我的头文件有一个全局变量,它被包含在多个CPP中?

回答

4

添加static可能会解决您的链接问题,但会给您一个更大的问题。该变量不再是全局变量,并且在每个使用它的CPP文件中具有不同的值。您需要在头文件中声明它为extern,然后在一个CPP文件中再次声明它。

当您使用static时,表示该变量将完全位于当前CPP文件的本地,并且不会暴露给其他文件。这就是为什么链接器不再在意在另一个具有相同名称的文件中是否存在另一个静态变量。它们不是同一个变量。

如果您想要一个真正的全局变量,它必须在一个CPP文件中声明,并且只有它的原型(与extern)应该位于将与其他CPP文件共享的头文件中。这完全像函数 - 在一个文件中声明,其余的原型。对于功能,你只是不提供一个机构。对于变量,您使用extern

3

如果你仔细想想,这很容易。该变量在头文件中定义,因此包含该头文件的每个.cpp文件都会获得自己的变量副本。现在,如果您不添加static,则所有.cpp文件都会通过外部链接获取相同的变量,并在编译时发生错误。

当您添加static时,每个.cpp仍然具有与来自相同定义的其他变量无关的变量,但它们不再具有外部链接,因此链接器不会发出错误。

但是不要忘记,每个变量都是一个单独的变量,它占用内存并且具有构建/销毁的开销,如果代码期望只有一个变量在所有.cpp文件中共享,您将会收到意想不到的行为。

相关问题