每个构造函数,方法和运算符重载的c ++多重定义错误[重复]

Posted

技术标签:

【中文标题】每个构造函数,方法和运算符重载的c ++多重定义错误[重复]【英文标题】:c++ multiple definition error for every constructor, method, and operator overload [duplicate] 【发布时间】:2013-02-19 08:42:58 【问题描述】:

我意识到这里已经有很多“多重定义”问题,但我在过去的 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;

...一切正常。但是,当我创建另一个仅包含 #include 语句的 .cpp 文件时...

DataReader.cpp

#include "Array.h"
#include "Vector.h"

...然后一切都崩溃了,我在 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&)'
TestMain.o:C:\C++\Eclipse CDT\workspace\3D_Adaptive_FEM\Debug/..//Vector.h:56: first defined here
DataReader.o: In function `ZNK6Vector1xEv':
C:\C++\Eclipse CDT\workspace\3D_Adaptive_FEM\Debug/..//Vector.h:59: multiple definition of `Vector::x() const'
TestMain.o:C:\C++\Eclipse CDT\workspace\3D_Adaptive_FEM\Debug/..//Vector.h:59: first defined here

etc...

但如果我在 DataReader.cpp 中只有 #include "Array.h",那么一切都运行良好!

#include "Vector.h" 可能有什么问题不适用于#include "Array.h"

编辑: 将实现分离成 .cpp 文件可以修复错误,但这并不能解释为什么我必须为 Vector 而不是 Array 这样做。

【问题讨论】:

这取决于Vector.h的内容。您在那里有一个非内联方法定义。 你有包括警卫吗? vector.h 是否包括 array.h 或相反?定义是inline吗? 没有看到Vector.hArray.h 就无法判断。 【参考方案1】:

我怀疑您在标题中对这些函数进行了离线定义。例如

#ifndef VECTOR_H
#define VECTOR_H

class Vector

public:
    Vector(int x, int y, int z);
private:
    int m_x, m_y, m_z;
;

Vector::Vector(int x, int y, int z)
    : m_x(x), m_y(y), m_z(z)


#endif

由于构造函数的定义没有内联在类定义中,因此编译器不会隐式地使其inline。现在,如果您在多个翻译单元(即*.cpp 文件)中包含同一个文件,链接器将产生您所看到的错误,因为每个*.cpp 文件都将包含其自己的构造函数定义,而不会标记它们作为内联函数。

解决方法很简单,只要在构造函数前面放一个inline声明

class Vector

public:
    inline Vector(int x, int y, int z);
    // ...
;

// ...

或者,如果函数体很短,如上所示的构造函数,直接将函数定义内联到类定义中,如

class Vector

public:
    Vector(int x, int y, int z)
        : m_x(x), m_y(y), m_z(z)
    
    // ...
;

// ...

【讨论】:

将接口与实现分开的另一个理由。在像初始化成员内联这样的微妙情况下可能没问题,但在更复杂的情况下,正确的方法是将实现移动到专用的 .cpp 源文件 @icepack 显然你从来没有用模板编程过......我知道英特尔编译器是唯一的例外,目前没有编译器允许你像他们那样将接口与模板的实现分开对于非模板代码。 关于内联/大纲模板定义的正确性存在一场圣战,但这是另一个话题。模板不是界面。 胡?为什么模板没有接口?只需声明模板类或模板函数就没有问题,只要您稍后交付实现或声明您在单独的翻译单元中为其提供实现的显式实例化/专业化。 @moodboom 不容易和不可能是两件不同的事情。

以上是关于每个构造函数,方法和运算符重载的c ++多重定义错误[重复]的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript实现多重继承

c++解决二义性的方法

多继承 与 多重继承

C++辅助函数的多重定义

多态性总结

OOP