41

<<クラスの演算子をオーバーライドしようとしています。目的は基本的にtoString()、クラスに同様の動作を実装して、それを送信するcoutと有用な出力が生成されるようにすることです。ダミーの例を使用すると、以下のコードがあります。コンパイルしようとすると、愚かなエラーが発生します。

$ g++ main.cpp Rectangle.cpp
/tmp/ccWs2n6V.o: In function `operator<<(std::basic_ostream<char, std::char_traits<char> >&, CRectangle const&)':
Rectangle.cpp:(.text+0x0): multiple definition of `operator<<(std::basic_ostream<char, std::char_traits<char> >&, CRectangle const&)'
/tmp/ccLU2LLE.o:main.cpp:(.text+0x0): first defined here

なぜこれが起こっているのかわかりません。私のコードは以下です:

Rectangle.h:

#include <iostream>
using namespace std;

class CRectangle {
    private:
        int x, y;
        friend ostream& operator<<(ostream& out, const CRectangle& r);
    public:
        void set_values (int,int);
        int area ();
};

ostream& operator<<(ostream& out, const CRectangle& r){
    return out << "Rectangle: " << r.x << ", " << r.y;
}

長方形.cpp:

#include "Rectangle.h"

using namespace std;

int CRectangle::area (){
    return x*y;
}

void CRectangle::set_values (int a, int b) {
    x = a;
    y = b;
}

main.cpp:

#include <iostream>
#include "Rectangle.h"

using namespace std;

int main () {
    CRectangle rect;
    rect.set_values (3,4);
    cout << "area: " << rect.area();
    return 0;
}
4

2 に答える 2

61

1 つの定義ルールを破っています。クイックフィックスは次のとおりです。

inline ostream& operator<<(ostream& out, const CRectangle& r){
    return out << "Rectangle: " << r.x << ", " << r.y;
}

その他は次のとおりです。

  • ヘッダー ファイルで演算子を宣言し、実装をRectangle.cppファイルに移動します。
  • クラス定義内で演算子を定義します。

.

class CRectangle {
    private:
        int x, y;
    public:
        void set_values (int,int);
        int area ();
        friend ostream& operator<<(ostream& out, const CRectangle& r){
          return out << "Rectangle: " << r.x << ", " << r.y;
        }
};

ボーナス:

  • インクルードガードを使用する
  • using namespace std;をヘッダーから削除します。
于 2012-10-09T14:43:05.413 に答える
20

関数の定義をファイルに入れてい.hます。つまり、それはすべての翻訳単位に表示され、One Definition Rule に違反します (=>operator<<すべてのオブジェクト モジュールで定義したため、リンカーはどれが「正しい」かわかりません)。 1")。

次のいずれかを実行できます。

  • 演算子の宣言(つまり、そのプロトタイプ)だけを .h ファイルに書き込み、その定義を次の場所に移動します。rectangle.cpp
  • make operator<< inline-inlineすべての定義が同一である限り、関数を複数回定義できます。

(また、インクルードではヘッダー ガードを使用する必要があります。)

于 2012-10-09T14:45:07.360 に答える