繁体   English   中英

为什么错误LINK2005:当我将对象声明为静态时,对象已定义的错误消失

[英]Why error LINK2005: object already defined error disappears when I declare the object as static

我有头文件中定义的结构和结构对象,如下所示:

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

struct STConfigurationDetails g_objConfigurationDetails ;

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

错误1错误LNK2005:“struct STConfigurationDetails g_objConfigurationDetails”(?g_objConfigurationDetails @@ 3USTConfigurationDetails @@ A)已在NDSClientDlg.obj中定义NDSConnectDlg.obj NDSClient

错误2致命错误LNK1169:找到一个或多个多重定义的符号d:\\ FromClearCase \\ Development_view \\ NDS_11152010 \\ exe \\ Debug \\ NDSClient.exe 1 NDSClient

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

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

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

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

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

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

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

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

全局静态变量具有内部链接

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM