3

ここには既に多くの「複数の定義」に関する質問があることを認識していますが、過去 2 時間かけて説明を探しましたが、見つかりませんでした。これが重複している場合は申し訳ありません。

現在、Array.h と Vector.h の 2 つのクラスがあります。どちらもグローバル変数を持たず、どちらも他方に依存していません (つまり、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...

しかし#include "Array.h"、DataReader.cpp だけを持っていれば、すべて正常に動作します。

#include "Vector.h"に当てはまらないことの何が間違っている可能性があります#include "Array.h"か?

編集: 実装を .cpp ファイルに分割するとエラーが修正されますが、配列ではなくベクトルに対してそれを行う必要がある理由が説明されていません。

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解決策は簡単です。コンストラクター宣言の前に a を置くだけです。

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 に答える