0

私は実践的な演習として数学ライブラリを書いています。=演算子をオーバーロードすると、いくつかの問題が発生しました。デバッグしたところ、vertex1=vertex2を呼び出すと代わりにコピーコンストラクターが呼び出されることに気付きました。

ヘッダーファイルには次のものがあります。

//constructors
vector3();
vector3( vector3 &v );
vector3(float ix, float iy, float iz);

//operator overloading
vector3 operator =(vector3 p);
....

私が実装したソースファイルでは、次のようになります。

vector3 vector3::operator =(vector3 p)
{
    vector3 v3;
    v3.x = p.x;
    v3.y = p.y;
    v3.z = p.z;
    return v3;
}

後で、外積法があり、次のように使用したいと思います。

vector3 v3;
v3 = v1.crossProduct(v2);

エラーメッセージは次のとおりです。エラー: `vector3 :: vector3(vector3)'を呼び出すための一致する関数がありませんが、コピーコンストラクターを呼び出したくありません。

4

6 に答える 6

4

コードに誤りがあります。コピー コンストラクターはconst&. 参照はコピーの作成を回避します (コピーコンストラクターであるため、これはconstできません)。変更していないため、そうする必要があります。

vector3(const vector3&);

一時変数は にバインドできますがconst&、可変参照にはバインドできません。つまり、コードを使用して次のことができます。

vector3 a;
vector3 b(a);

だがしかし:

vector3 a(some_calculation()); // some_calculation returns a vector3

さらに、あなたoperator=は間違っています。コピー コンストラクターと同様に、通常は を受け取りますがconst&への参照を返す必要がありますthis。それが連鎖の仕組みです:

int a, b, c;
a = b = c = 0;
// a.operator=(b.operator=(c.operator=(0)));

一時的なものを返すことは非正統的であり、何も達成しません。あなたの場合、何度も割り当てて値を変更することはできません。奇妙な:

vector 3 a, b;
a = b; // doesn't change a...?!

operator=変更する必要がありますthis

于 2010-02-14T16:39:33.730 に答える
2

vector3(vector3&v);

それは本当にあるべきですvector3( const vector3 &v );

一時的な値を返すため、const参照を取得するcopy-constructorを呼び出す必要があります。

于 2010-02-14T16:25:58.643 に答える
2

コピー コンストラクターを呼び出したくありません。

あなたが望むものは無関係です。ここにはコピー コンストラクターが必要です。operator =この状況では呼び出されません。コピー コンストラクターが呼び出されます。その上、署名が間違っています。

vector3& operator =(vector3 const& other);

引数は値で渡すこともできます (ただし、これは高度なトリックです...) が、戻り値は実際には非 const 参照でなければなりません。

(コピー コンストラクターの署名も型破りです。James の回答を参照してください。)

于 2010-02-14T16:34:35.517 に答える
1

vector3 vector3::operator =(vector3 p)代わりに参照を使用して、コピーを作成する必要がないようにしてください。

vector3& vector3::operator =(vector3& p);

とにかく、そもそもコピーされたオブジェクトを作成したくありませんでした。

于 2010-02-14T16:25:27.210 に答える
1

C++ では、オブジェクトをコピー可能にする (つまり、別の変数に代入可能にする) かどうかに応じて、2 つのいずれかを実行することをお勧めします。その場合は、代入演算子とコピー コンストラクターの両方を提供する必要があります。例えば:

class Point
{
public:
    Point ()                          { }
    Point (int x, int y)              : mX(x), mY(y) { }
    Point (const Point& p)            : mX(p.mX), mY(p,mY) { }

    Point& operator = (const Point& p)    { mX = p.mX; mY = p.mY; return *this; }

    int X () const                    { return mX; }
    int Y () const                    { return mY; }

private:
    int mX;
    int mY;
};

コピー可能にしたくない場合は、コピー コンストラクターと代入演算子の両方のプロトタイプをプライベート セクションに配置し、実装を提供しないでください。それをコピーしようとすると、コンパイラ エラーが発生します。

この種のコードを使用するときはいつでも:

Point P = anotherP;

コピー コンストラクターが呼び出されます。このタイプのコードを使用する場合:

Point P;
P = anotherP;

代入演算子が呼び出されます。

それが役立つことを願っています。

于 2010-02-14T16:46:23.803 に答える
0

operator = の定義にあるように、「値渡し」すると、メソッドのローカル値として使用するために型のコピーが作成されます。システムが vector3 を受け取るコンストラクターを見つけられないため、オペレーターが呼び出されていません。vector3& を受け取るコピー コンストラクターを定義しました。

したがって、他の人が述べているように、あなたがしたいことは、演算子 = を次のように定義することです

const vector3& p

また、宣言されたコピー コンストラクターを更新して、const vector3 も取得する必要があります。

于 2010-02-14T16:42:15.483 に答える