我是C++的新手.我对C++中的多个定义错误有些怀疑.
假设我在一个程序中有3个文件.一个头文件和两个.cpp文件.我已将头文件包含在.cpp文件中.
我们可以通过extern在头文件中使用并仅在一个文件中定义类来解决这个问题吗?如果我们可以通过使用此方法解决问题,我们是否必须将.cpp(带有类定义)包含到其他.cpp文件中(没有课程定义)?
我在头文件中声明并定义了一个类.这种情况是否与上述相同(1中提到)?
我在头文件中声明了一个类,我在每个.cpp文件中定义了类,但定义(函数体)不同.那么这种类型的实现会导致多个定义错误吗?如果是这样,我们如何解决.cpp文件中函数体不同的问题?
创建以下类后,编译失败,出现许多"重复符号"错误.实际错误不是很具描述性:
"复制符号__Zeq .... in:/Users/myusername/Library/Developer/Xcode/DerivedData/MyProject-asdfasfasdf..../Build/Intermediates/MyProject.build/Debug-iphonesimulator/MyTarget.build/Objects-normal /i386/MyClass.o"
上面相同的消息出现在许多不同的类中,并出现在编译结束时,所以我不知道问题是什么.
我检查了以下内容:
问题是什么?
#ifndef Listening_hpp
#define Listening_hpp
#include <stdio.h>
#include "EAction.hpp"
class Listening{
private:
int _emitterId;
int _listenerId;
std::string _eventName;
EAction* _actionToTake; //not owned.
protected:
public:
Listening(int emitterId,int listenerId,std::string eventName,EAction* actionToTake) : _emitterId(emitterId),_listenerId(listenerId),_eventName(eventName){
_actionToTake = actionToTake;
}
int getEmitterId()const{
return _emitterId;
}
int getListenerId()const{
return _listenerId;
}
std::string getEventName()const{
return _eventName;
}
EAction* getAction()const{
return _actionToTake;
}
};
bool operator==(const Listening &first,const Listening &other)
{
bool result = false;
if(first.getEmitterId() == other.getEmitterId()){
if(first.getListenerId() …Run Code Online (Sandbox Code Playgroud) 我正在尝试在 QTCreator for Windows 中测试我已经完成的库(微积分)。
我已经创建了一个主文件,并在一个单独的文件中创建了一个用于测试的类。如果我编译http://www.boost.org/doc/libs/1_47_0/libs/test/doc/html/utf/user-guide/test-organization/manual-test-suite.html 中的示例,它就可以工作,以及http://www.boost.org/doc/libs/1_47_0/libs/test/doc/html/utf/user-guide/test-organization/manual-nullary-test-case.html 中的示例也有效。
但是当我尝试编译我的项目时,我有很多(超过 500 个)多个定义的错误。您可以在下面找到我的文件。正如你所看到的,我也试图在 boost 头周围设置一些保护,但它不起作用。我究竟做错了什么?
主程序
#include "testcalculus.h"
#ifndef USE_BOOST_HEADERS
#define USE_BOOST_HEADERS
#include <boost/test/included/unit_test.hpp>
#include <boost/bind.hpp>
#endif
using namespace boost::unit_test;
test_suite*
init_unit_test_suite( int argc, char* argv[] )
{
WRayTesting::TestCalculus xTestCalculus;
test_suite* pxTestSuiteCalculus = BOOST_TEST_SUITE("Test Calculus");
pxTestSuiteCalculus->add(BOOST_TEST_CASE( boost::bind(&WRayTesting::TestCalculus::testCartesianPoint2D, &xTestCalculus)));
framework::master_test_suite().add(pxTestSuiteCalculus);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
testcalculus.h
#ifndef TESTCALCULUS_H
#define TESTCALCULUS_H
#ifndef USE_BOOST_HEADERS
#define USE_BOOST_HEADERS
#include <boost/test/included/unit_test.hpp>
#include <boost/bind.hpp>
#endif
#include "cartesianpoint2d.h"
#include "cartesianvector2d.h"
namespace WRayTesting
{
/** Class for testing the …Run Code Online (Sandbox Code Playgroud) 我第一次在一个项目中使用多个 C++ 文件。两者都需要包含受保护的(#ifndef)头文件。但是,当我这样做时,我收到了多重定义错误。
我拥有的是两个直接调用标头的 .cpp 文件,一个间接调用标头的文件(另一个包含它),然后是包含它的另外两个头文件。
那么我需要做什么来消除错误呢?
错误:
obj\Debug\main.o||在函数
Z14sortLibQtyTest4BookS_':| [PATH]\miscFuncs.h|16|multiple definition ofsortLibQtyTest(Book, Book)'
代码:
bool sortLibQtyTest(Book a, Book b){ return a.getQty() > b.getQty(); }
Run Code Online (Sandbox Code Playgroud)
应该提到的是,这并不是唯一给我带来问题的函数,可能有十多个,而且有些不是那么短和甜蜜。此外,多个文件中都需要这些函数。
我正在尝试编译代码,它正在获得多个定义的链接错误.不幸的是,我无法解决它,任何帮助将不胜感激.
我有以下文件:头文件:CEST.h; CEST_UI.h; GlobalVariable.h;
源文件:CEST.cpp; CEST_UI.cpp; GlobalVariable.cpp
声称具有多个定义的所有参数在"GlobalVariable.h"中定义,并在"GlobalVariable.cpp"中初始化.
我两次包括"GlobalVariable.h":一次在CEST.cpp中,第二次在CEST_UI.cpp中.
我在想"GlobalVariable.h"中的后续保护会保护我多重定义链接错误:
# ifndef GLOBALVARIABLE_H
#define GLOBALVARIABLE_H
………….
………….
#endif
Run Code Online (Sandbox Code Playgroud)
我还附加了"GlobalVariable.h"和"GlobalVariable.cpp",以便您可以查看.
在"GlobalVariable.h"中
# ifndef GLOBALVARIABLE_H
#define GLOBALVARIABLE_H
#include <vector>
////////////////////////////////////////
extern long lFA_MTPulse;
extern long lNoOfMTPulses;
extern long ltDK_MTPulse_Duration_us;
//extern long ltDK_MTPulse_Delay_us;
extern long ltDK_Wait_After_MT_us;
extern long ltDK_Wait_After_MTSpoil_us;
extern long lNoOfMTPulses_PerRTEB;
extern long ltDK_PreAcqCESTPulseTime_ms;
extern long ltDK_PreAcqCESTPulseTime_us;
extern long lTest_XgradStrength;
//double TR_MTPulse_Remain = 0.0; // CEST This will be calculated later
long ltDK_TR_MTPulse_us;
long ltDK_TimeNeeded_for_sMTCSpoilerOnly;
long ltDK_MTBlockTime_DK;
////////////////////////////////////////
extern double dBWTimeProd;
extern …Run Code Online (Sandbox Code Playgroud) 我得到了全局的上述消息链接器错误
const char* HOST_NAME = "127.0.0.1";
Run Code Online (Sandbox Code Playgroud)
我不认为我已经编译了两次文件,但这里是我对文件的定义.
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include "connection.hpp"
Run Code Online (Sandbox Code Playgroud)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <arpa/inet.h>
#include "connection.hpp"
Run Code Online (Sandbox Code Playgroud)
#ifndef __connection__
#define __connection__
#include <unistd.h>
#include <netinet/in.h>
const int BUFFSIZE = sysconf(_SC_PAGESIZE); //Define page size
const char* HOST_NAME = "127.0.0.1"; //Local host
//Definition of a class
#endif
Run Code Online (Sandbox Code Playgroud)
有帮助吗?
我有2个库:test.1和test.2.两个库都包含单个全局extern"C" void f();函数,具有不同的实现(仅cout用于测试).
我做了以下测试:
测试1动态链接:
如果我添加libtest.1.so,然后libtest.2.so在可执行文件的生成文件,然后调用f();中main,libtest.1.so->f()被调用.
如果我更改makefile中的顺序,libtest.2.so->f()则调用
测试2静态链接:
静态库完全相同
测试3动态加载
手动加载库时,一切都按预期工作.
我预计多个定义会出错,这显然不会发生.
此外,这不会打破单一定义规则,因为情况不同.
它也不是一个依赖地狱(不是它与此有关),也不是任何链接惨败..
那么,这是什么呢?未定义的行为?未指明的行为?或者它确实取决于链接顺序?
有没有办法轻松检测到这种情况?
相关问题:
dlopen与链接开销
动态链接和动态加载之间的区别
使用-Bsymbolic函数是否存在缺点?
为什么库链接的顺序有时会导致GCC错误?
将两个共享库与一些相同的符号链接起来
编辑我做了两个测试,证实了这个UB:
我添加了第二个函数void g()中test.1,而不是在test.2.
使用动态链接和.so库,同样的事情 - f以相同的方式调用,g也是可执行的(如预期的那样).
但是使用静态链接现在改变了一些事情:如果test.1是之前 test.2,没有错误,test.1则会调用两个函数.
但是当订单更改时,会出现"多个定义"错误.
很明显,"不需要诊断"(参见@MarkB的答案),但有时候发生错误是"奇怪的",有时候 - 它没有.
无论如何,答案很清楚,并解释了上面的一切 - UB.
c c++ dynamic-linking multiple-definition-error static-linking
我想知道__attribute__((selectany))在Linux中是否还有替代方法?
我想定义这样的东西:
char * a[] = { "qwe", "zxc" };
Run Code Online (Sandbox Code Playgroud)
在头文件中,并将其包含在许多将链接在一起的.c文件中。因此,链接器将看到一个以上的“ a”定义,因此将不会链接。我已经读过这个属性(selectany),它将仅使用“ a”的第一个定义,不幸的是,它仅用于ms窗口。所以问题是:linux中有替代方法吗?
编辑:实际的问题是:有没有一种方法可以指示链接器仅使用第一个看到的定义,而忽略其他任何可能的定义,即使它们不同?我知道有很多方法可以定义我的数据,我不是在寻找解决方案来定义我的数据,相反,我想知道是否有一种方法可以有多个定义并使链接器与第一个看到的一样工作。 ..
我已经意识到这里已经存在很多"多重定义"的问题了,但是我花了2个多小时寻找解释而没有找到解释.很抱歉,如果这是重复的话.
现在我有2个类:Array.h和Vector.h.既没有任何全局变量,也没有依赖于另一个(即Array不使用Vector而Vector不使用Array).实现在.h文件中.
这是我的Main.cpp:
#include <iostream>
#include "Array.h"
#include "Vector.h"
using namespace std;
int main() {
cout << "Done" << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
......一切都运行良好.但是,当我使用#include语句创建另一个.cpp文件时......
DataReader.cpp
#include "Array.h"
#include "Vector.h"
Run Code Online (Sandbox Code Playgroud)
...然后一切都爆炸了,我在Vector中的每个方法,构造函数和运算符重载都得到了一大堆错误:
DataReader.o: In function `Vector':
C:\C++\Eclipse CDT\workspace\3D_Adaptive_FEM\Debug/..//Vector.h:49: multiple definition of `Vector::Vector()'
TestMain.o:C:\C++\Eclipse CDT\workspace\3D_Adaptive_FEM\Debug/..//Vector.h:49: first defined here
DataReader.o: In function `Vector':
C:\C++\Eclipse CDT\workspace\3D_Adaptive_FEM\Debug/..//Vector.h:53: multiple definition of `Vector::Vector(int const&, int const&, int const&)'
TestMain.o:C:\C++\Eclipse CDT\workspace\3D_Adaptive_FEM\Debug/..//Vector.h:53: first defined here
DataReader.o: In function `Vector':
C:\C++\Eclipse CDT\workspace\3D_Adaptive_FEM\Debug/..//Vector.h:56: multiple definition of `Vector::Vector(double const&, double const&, double const&)' …Run Code Online (Sandbox Code Playgroud) 好的,所以我在过去的4个小时里一直在搜索这个"多个定义首先定义在这里"问题的每个论坛,我想我一定是非常愚蠢的,但我似乎无法解决这个问题.
我有以下文件:
main.cpp
Socket.h
Socket.cpp
Server.h
Server.cpp
Packet.h
FileHandlerIn.h
FileHandlerOut.cpp
Run Code Online (Sandbox Code Playgroud)
main.cpp仅包含Server.h,它声明了一些函数,然后在Server.cpp中定义.
Server.cpp使用来自Socket.cpp,FileHandlerOut.cpp和Packet.h功能,所以头文件socket.h中,Packet.h和FileHandlerIn.h包括在Server.h.其他头文件都不包含除标准库之外的任何内容.
发生的事情是Server.cpp中的每个函数和Packet.h中的每个函数都会出现多重定义错误.我在Packet.h中有函数的原因是我定义了一个struct,而Packet.h函数都在struct上运行.我真的很困惑我应该如何正确定义这些函数,所以我可以在其他cpp文件中使用它们,这可能是我的问题的一部分?