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"
...
这些是我收到的错误:
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"
...