包含外部库时出现C++多重定义错误
C++ multiple definition error when including external library
我正在尝试编写一个简单的应用程序,允许用户对一组线性方程执行一系列符号操作,并为此使用"Symbolicc++"库(更具体地说,最新版本3.35)。
由于我对C++没有太多经验,而且以前从未真正使用过第三方库,所以很可能我根本不知道如何正确使用库,并犯了一些愚蠢的错误。
问题是,当我试图编译(和链接)由多个文件组成的任何程序(包括库的主标题)时,我会得到很多定义错误;这些错误指的是库文件中定义的函数和类(而不是我的)。
一个非常简单的例子:假设我们有main.cpp、head.h和header.cpp文件。内容如下:
main.cpp
------------------
#include <iostream>
#include "head.h"
int main()
{
return 0;
}
head.h
------------------
#ifndef SOMETHING
#define SOMETHING
#include "symbolicc++.h"
#endif
head.cpp
------------------
#include "head.h"
//nothing
当然,真实程序中的文件包含更多,但即使只有这些,也要尝试使用以下方法构建程序,例如:
g++ -I /path to library's header files/ main.cpp head.cpp
产生数百条错误消息,如:
/tmp/ccYNzlEF.o: In function `Cloning::Cloning()':
head.cpp:(.text+0x0): multiple definition of `Cloning::Cloning()'
/tmp/ccNWUnnC.o:main.cpp:(.text+0x0): first defined here
其中,例如,Cloning::Cloning()在Cloning.h中声明,该文件是库的头文件之一。
一个只包含单个文件(包括symbolicc++.h)的程序运行良好。
我还尝试在VisualStudio2012上构建这个项目,并得到了类似的结果。
不幸的是,我找不到任何关于这个问题的信息,因为我发现的几乎所有材料都涉及用户创建的头文件中的错误(而不是其他人创建的库),所以如果有任何帮助,我们将不胜感激。
这个库似乎严重损坏。按照它的设计方式,在不违反一个定义规则的情况下,不能多次包含"symbolicc++.h"
。
例如,让我们来看看cloning.h
。它定义了一个带有默认构造函数声明的Cloning
类:
class Cloning
{
private: int refcount;
void (*free_p)(Cloning*);
// ...
public: Cloning();
// ...
};
稍后,在头文件中,它还定义了构造函数:
Cloning::Cloning() : refcount(0), free_p(0) {}
就是这样。直接或间接包含cloning.h
的*.cpp文件中的每一个都将暴露在同一函数的定义中。链接器注意到多个定义并放弃。
尝试修改cloning.h
。删除上面的构造函数定义行,并将构造函数定义放入类定义中,使其成为内联函数:
// just to see what's going on...
class Cloning
{
private: int refcount;
void (*free_p)(Cloning*);
// ...
public: Cloning() : refcount(0), free_p(0) {};
// ...
};
这将修复Cloning::Cloning
的错误。但这只是为了进一步阐明这个问题;我不建议你这么做修复他们的代码将是库作者的工作
进一步推荐阅读:为什么包含保护不能阻止多个功能定义?
这里有一种方法可以让你用自己的几行代码重现同样的问题:
水头h:
#ifndef SOMETHING
#define SOMETHING
struct Example
{
Example(); // constructor declaration
};
Example::Example() // constructor definition
{
}
#endif
head.cpp:
#include "head.h"
//nothing
main.cpp:
#include "head.h"
int main()
{
}
链接器错误示例(取自Visual C++2013):
1>main.obj : error LNK2005: "public: __thiscall Example::Example(void)" (??0Example@@QAE@XZ) already defined in head.obj
1>[...] fatal error LNK1169: one or more multiply defined symbols found
如果你绝对必须使用这个库,你就必须围绕它构建自己的安全包装。但坦率地说,不要这样做。我相信还有许多其他库可以解决同样的问题,并且实际上可以根据C++语言规则和约定使用这些库。
- 使用命名空间时出现多个定义错误
- 对C宏的未定义引用,但在定义它时会出现重新定义错误
- 尝试调用 .h 文件中定义的变量时出现变量未定义错误
- 在头文件和 cpp 文件中使用一次 #pragma 时出现结构重定义错误
- 链接阶段出现多重定义错误
- 避免模板类中的重定义错误
- 即使我没有包含多个文件,C++中的多个定义错误
- 跨多个类的全局变量而不会出现重定义错误?
- 尝试运行 wasm 函数时出现模块未定义错误
- C++ 预期的左大括号以及重定义错误
- C++:成员的越界声明必须是纯虚函数的定义错误
- c++中数组的未定义错误
- Visual C:模板类中的自定义错误消息
- 为什么C++模板不会导致多个定义错误?
- 只有一个定义/声明时标头声明变量的多堆定义错误
- C++ 在多个其他类中使用单个类 - 编译时出现多个定义错误
- 基类未定义.错误 C2504
- Q 斯坦达项重定义错误
- 可视化C++中的结构定义错误
- VC++ C2011 重定义错误 - 未使用的头文件