我正在写一个数学库作为实践练习。我在重载=运算符时遇到了一些问题。当我调试它时,我注意到对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)'的匹配函数 但我不想调用复制构造函数。
答案 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。