从未在C ++中调用重载的运算符

时间:2010-02-14 16:21:29

标签: c++ overloading equals copy-constructor

我正在写一个数学库作为实践练习。我在重载=运算符时遇到了一些问题。当我调试它时,我注意到对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;
}

后来我有一个crossproduct方法,我想这样使用它:

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

错误消息是:     错误:没有用于调用`vector3 :: vector3(vector3)'的匹配函数 但我不想调用复制构造函数。

6 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

  
    

vector3(vector3& v);

  

那真的应该是vector3( const vector3 &v );

由于返回临时值,因此必须调用带有const引用的copy-constructor。

答案 2 :(得分:2)

  

我不想调用复制构造函数。

你想要的是无关紧要的。你需要一个拷贝构造函数。在这种情况下,operator =不会被调用,复制构造函数是。此外,签名是错误的,应该是

vector3& operator =(vector3 const& other);

参数也可以通过值传递(但这是一个高级技巧......)但返回值确实必须是非const引用。

(复制构造函数的签名也非常规,请参阅James的回答。)

答案 3 :(得分:1)

vector3 vector3::operator =(vector3 p)使用引用,这样您就不需要创建副本了。

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

无论如何,您不想首先创建复制的对象。

答案 4 :(得分:1)

在C ++中,根据您是否希望对象可复制(即可分配给另一个变量),可以执行以下两种操作之一。如果需要,您需要同时提供assign运算符和复制构造函数。例如:

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;
};

如果您不希望它可复制,您可以将复制构造函数和assign运算符的原型放在私有部分中,并且不提供实现。任何尝试复制它都会给编译器错误。

每当你使用这种代码时:

Point P = anotherP;

将调用复制构造函数。如果您使用此类代码:

Point P;
P = anotherP;

将调用assign运算符。

希望有所帮助。

答案 5 :(得分:0)

当您按“值传递”时,正如您在operator =的定义中那样,将使用该类型的副本作为方法的本地值。您的操作符未被调用,因为系统找不到带有vector3的构造函数 - 您已经定义了一个带有vector3&的复制构造函数。

因此,正如其他人所说,您要做的是将您的operator =定义为

const vector3& p

您还应该更新声明的复制构造函数以使用const vector3。