3

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

数据读取器.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...

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

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

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

4

1 回答 1

9

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

#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)
    {}
    // ...
};

// ...
于 2013-02-19T08:57:15.717 回答