c语言error lnk 2005,C ++中的即时对象初始化失败,出现LNK2005错误(Instant object initialization in C++ fails with LNK200...

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线程或连接的微软网站上搜索,但都没有帮助。

这些是我的文件:

Source.cpp

#include

#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文件中,而不是立即在头文件中执行,但由于即时初始化是可能的,那么为什么我不能使用它呢?

These are the errors that I've been receiving:

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

and

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

I don't really understand where are these errors coming from. I've tried searching in other SO threads or on the connected Microsoft's website, but none helped.

These are my files:

Source.cpp

#include

#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;

}

What I know is that it's enough to move the object initialization into the Source.cpp file and not do it instantly in the header file, but since the instant initialization is a possibility then why wouldn't I use it?

原文:https://stackoverflow.com/questions/46636389

更新时间:2020-01-18 03:12

最满意答案

假设您有两个不同的.cpp文件,每个文件都包含您的Header.h标头。 然后,每个.cpp文件都会将此代码合并到其中:

class Sally

{

public:

bool ReturnTruth();

} TestObject;

因此,每个文件都包含Sally类型的名为TestObject的对象的定义。 这打破了单定义规则,因为在所有翻译单元中,每个对象最多只能有一个定义,并且它在链接器错误中显现出来。

如果您确实要声明Sally类型的全局对象,请更改标头以声明类型为Sally的extern对象,如下所示:

class Sally

{

public:

bool ReturnTruth();

};

extern Sally TestObject;

这是一个声明 ,而不是一个定义 ,并且可以对对象进行冗余声明。

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

Sally TestObject;

这将对象的定义放在一个位置,因此修复了单定义规则问题和链接器问题。

Let's suppose that you have two different .cpp files that each include your Header.h header. Then, each one of those .cpp files gets this code incorporated into it:

class Sally

{

public:

bool ReturnTruth();

} TestObject;

As a result, each file contains the definition of an object named TestObject of type Sally. This breaks the one-definition rule, since there's only supposed to be at most one definition of each object across all translation units, and it's manifesting in your linker error.

If you do want to declare a global object of type Sally, change the header to declare an extern object of type Sally, like this:

class Sally

{

public:

bool ReturnTruth();

};

extern Sally TestObject;

This is a declaration, not a definition, and it's okay to have redundant declarations of objects.

Then, pick a .cpp file - probably the one where you implement the Sally member functions - and add this line:

Sally TestObject;

That puts the definition of the object in a single place, and so fixes the one-definition-rule issue and the linker issue.

2017-10-08

相关问答

我想我知道发生了什么事。 Unity.cpp包含Verbose.cpp和Client.cpp -Verbose.cpp具有print的实现 。 -Client.cpp包含Verbose.hpp,它引入了print的实现。 所以Unity.obj有2个print实现。 这意味着库(LibProj.lib)包含一个带有打印重复项的.obj文件。 因此,当我们尝试链接到库时,编译器不知道要使用哪个打印 。 这对常规构建起作用的原因是,通常,Verbose.cpp创建Verbose.obj,其中包含pri

...

虽然通常建议为您构建的每个可执行文件创建一个项目,但如果您设法以某种方式摆脱不需要的重复主电源,则可以为多个可执行文件设置单个项目。 您有很多选择: 只有一个主要。 让它测试自己的可执行文件名,并根据它找到的名称采取特定的操作。 在构建后规则中,设置用于从基本可执行文件创建每个(特别命名的)可执行文件的规则。 这允许您以相当有效的方式同时构建所有可执行文件。 有多个主电源,但使用#ifdefs隐藏它们。 将#define添加到项目设置或main()之上的某处,然后根据需要进行编译。 如果您不想一直

...

这是头文件的常见问题,包含实现。 当您使用#include指令时,编译器只是插入.h文件内容而不是它。 因此,当您在项目的不同位置使用此标头时,您将获得其方法和全局变量的几个相同实现。 因为它有#ifdef或#pragma once编译器保护,它编译就好了。 但是当链接器试图将所有已编译的obj文件统一到一个可执行模块时,它会获得几个相同的实现。 由于无法知道应该使用哪一个,因此会出现LNK2005错误。 要解决此问题,您可以将实现和全局变量移动到单独的cpp文件中并将其包含在项目中。 其他方法是

...

#include "SQueue.cpp" // KILL THIS or exclude SQueue.cpp in compilation process

#include "SQueue.cpp" // KILL THIS or exclude SQueue.cpp in compilation process

错误说你有多个符号定义。 最有可能的是,您在其他一些文件(您没有共享Connect_Four_Game文件)中多次(直接或间接)包含Player.cpp文件(而不是Player.h)。 我建议你做一些研究:如果你包含.cpp文件会发生什么? 阅读关于声明,定义,多重包含,...。 这也很有用: 已经在.obj中定义 - 没有双重包含 我开始像你一样,提出不好的问题(我想每个人都这样做)。 下一次,您应该尝试检测链接器错误发生的位置,并知道链接器错误是什么。 我记得我在C ++开始的日子。 正如你明

...

您正在头文件中定义您的方法。 当您将该头文件包含在多个翻译单元中时,这意味着有多个定义。 这是链接器在抱怨时说的: .... already defined ....

将方法的定义移出.h文件并放入.cpp文件。 You are defining your methods in the header file. When you include that header file in multiple translation units, that means that there are mu

...

假设您有两个不同的.cpp文件,每个文件都包含您的Header.h标头。 然后,每个.cpp文件都会将此代码合并到其中: class Sally

{

public:

bool ReturnTruth();

} TestObject;

因此,每个文件都包含Sally类型的名为TestObject的对象的定义。 这打破了单定义规则,因为在所有翻译单元中,每个对象最多只能有一个定义,并且它在链接器错误中显现出来。 如果您确实要声明Sally类型的全局对象,请更改标头以声明类型为Sally的

...

第二种方法是正确的。 您只需要在.cpp文件中定义extern变量。 添加 int X::var = 0;

int Y::var = 0;

int Z::var = 0;

到HeaderRealiseOne.cpp将解决问题。 The second approach is correct. You just need to define the extern variables in a .cpp file. Adding int X::var = 0;

int Y::var = 0;

int

...

你已经到处都是全局变量,但没有在任何地方定义它。 extern没有定义变量。 它只是告诉编译器变量是在别处定义的。 所以你必须在其他地方实际定义它。 你可以这样做。 在头文件中 /* main.h */

MYEXTERN Game TheGame;

MYEXTERN Graphics TheGraphics

在第一个.c文件中 在main.cpp中 /* MYEXTERN doesn't evaluate to anything, so var gets defined here */

#de

...

这个: vector vect;

vector::iterator ab;

是标题中的定义,这意味着当您在多个翻译单元中包含标题时,您将打破一个定义规则。 将其更改为: //abc.h

extern vector vect;

extern vector::iterator ab;

使其成为声明并在单个实现文件中移动定义: //abc.c

#include "abc.h"

vector vect;

vector

...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值