2

いくつかの単純でばかげたテストを書くことによって、演算子のオーバーロードの概念を理解しようとしています。これはC++をよりよく理解するのに役立つので、これは役立つかもしれないと思いました。

なぜこの例はAnimalクラスの連結演算子を実装し、std::stringコンパイルしないのですか?G++では次のエラーが発生します。

追加の資格'Animal::' on member'operator +'[-fpermissive]

これはコードです:

#include <iostream>
using namespace std;

class Animal {

public:
    string _type;
    string _name;
    string _sound;


    Animal & Animal::operator+(const string & o);
};


Animal & Animal::operator+(const string & o) {
    cout << "plus operator \n";
    this->_name=o;
    return *this;
}


int main( int argc, char ** argv ) {
    Animal a;

    a+"hhh";
    cout<<a._name;
    return 0;
}
4

4 に答える 4

4
Animal & Animal::operator+(const string & o);

無効です。そのはず:

Animal & operator+(const string & o);

また、単純な加算演算子を実装すると、オペランドの1つが変更されます。これは、加算演算子にとって決して良いことではありません。

例えば:

int a, b = 5, c = 3;
a = b + c;

どちらのオペランドの値も変更されません。そのままbにしcて、まったく異なるインスタンスを返します。

したがって、加算演算子をオーバーロードするのではなく、加算代入複合演算子(+=)をオーバーロードする必要があります。

Animal & operator+=(const string & o);

そしてもちろん、実装を変更し、それに応じてそれを呼び出します。

Animal & Animal::operator+=(const string & o) {
    cout << "plus operator \n";
    this->_name=o;
    return *this;
}

と:

a += "hhh";
于 2013-02-02T15:59:54.097 に答える
2

operator+クラス内で宣言されているという理由だけで、クラス内の宣言を修飾する必要はありません。

class Animal {
  // ...
  Animal& operator+(const string& o);
}

この修飾は、関数をクラスの外部で定義するために定義するときに必要です。コンパイラは、関数がどのクラスに属しているかを知る必要があります。

于 2013-02-02T16:00:10.523 に答える
0

プロトタイプにはすでにクラスAnimal::内にあるため、の必要はありません。Animal使用するだけです:

Animal & operator+(const string & o);
于 2013-02-02T16:00:09.797 に答える
0

Animal::修飾は、宣言ではなく、メンバー関数の定義で使用する必要があります。したがって、演算子宣言を次のように変更します。

Animal & operator+(const string & o);
于 2013-02-02T16:00:39.213 に答える