C++ 中的即时对象初始化失败并出现 LNK2005 错误

Instant object initialization in C++ fails with LNK2005 error

这些是我收到的错误:

LNK2005 "class Sally TestObject" (?TestObject@@3VSally@@A) already defined in Source.obj    Project2    c:\Users\W8User\documents\visual studio 2015\Projects\Project2\Project2\Source1.obj

LNK1169 one or more multiply defined symbols found  Project2    c:\users\w8user\documents\visual studio 2015\Projects\Project2\Debug\Project2.exe

我真的不明白这些错误是从哪里来的。我试过在其他 SO 线程或连接的 Microsoft 网站上搜索,但 none 有所帮助。

这些是我的文件:

Source.cpp

#include <iostream>
#include "Header.h"

int main() {

    std::cout << TestObject.ReturnTruth();

    return 0;
}

Header.h

#pragma once

class Sally
{
public:

    bool ReturnTruth();

} TestObject;

Source1.cpp

#include "Header.h"

bool Sally::ReturnTruth()
{
    return 1;
}

我所知道的是,将对象初始化移动到 Source.cpp 文件中就足够了,而不是在头文件中立即执行,但既然即时初始化是可能的,那我为什么不使用它?

#include "Header.h" 的每个地方都会有一个 TestObject 的实例,除非你的编译器可以将所有这些折叠成一个单例,否则你将有几个独立的、不相关的实例。

该错误告诉您您犯了一个错误。解决这个问题的一种方法是在头文件中定义:

extern Sally TestObject;

这明确表明这将在别处实例化。然后在 Source1.cpp:

中创建一个显式实例
Sally TestObject;

然后你的主文件就会知道去哪里找这个东西。

不清楚你是否首先想要一个单例。为什么不能在 main 中实例化一个并使用它?

请注意,花点时间给您的源文件起一个有意义的名字。

假设您有两个不同的 .cpp 文件,每个文件都包含您的 Header.h header。然后,这些 .cpp 文件中的每一个都将这段代码合并到其中:

class Sally
{
public:

    bool ReturnTruth();

} TestObject;

因此,每个文件都包含类型为 Sally 的名为 TestObject 的 object 的定义。这违反了 one-definition 规则,因为所有翻译单元中每个 object 最多只能有一个定义,并且它会在您的链接器错误中体现。

如果您确实要声明类型 Sally 的全局 object,请更改 header 以声明类型 extern object 15=],像这样:

class Sally
{
public:

    bool ReturnTruth();

};
extern Sally TestObject;

这是一个声明,而不是定义,可以有object的冗余声明。

然后,选择一个 .cpp 文件 - 可能是您实现 Sally 成员函数的文件 - 并添加以下行:

Sally TestObject;

这将 object 的 定义 放在一个地方,因此修复了 one-definition 规则问题和链接器问题。

通过在 class 定义 Sally 之后直接附加标识符 TestObject,您可以在头文件中定义一个变量。所以如果不同的翻译单元包含这个头文件,一个同名的变量被定义两次,导致链接器错误。您可以通过 声明 变量来解决此问题,即在头文件中使用 extern-关键字,而 定义 变量则完全一个 .cpp-文件:

所以写:

Header.h

class Sally
{
public:

    bool ReturnTruth();

};

extern Sally TestObject;

Source1.cpp

#include "header.h"

Sally TestObject;
...

在所有其他 CPP 文件中:

#include "header.h"
...