重载操作符是永远不会用C ++叫
-
20-09-2019 - |
题
我正在写一个数学库的实战演练。我重载=运算符时碰到一些问题。当我debuged它,我注意到,在调用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)没有匹配的函数” 但我不想调用拷贝构造函数。
解决方案
有在代码中的错误。你的拷贝构造函数必须采取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
。
其他提示
的Vector3(的Vector3&V);
这真的应该vector3( const vector3 &v );
由于你的回报临时值,则必须调用拷贝构造函数参数类型为const引用。
我不想调用拷贝构造函数。
你想要的是不相关的。您的需要的拷贝构造函数在这里。 operator =
不会被调用在这种情况下,拷贝构造。此外,签名是错误的,它应该是
vector3& operator =(vector3 const& other);
的参数也可以通过值传递在(但是这是一种先进的特技...),但在返回值确实必须是一个非const参考。
(你的拷贝构造函数的签名也是标新立异,看到詹姆斯的回答。)
请vector3 vector3::operator =(vector3 p)
使用引用代替你不需要创建副本。
vector3& vector3::operator =(vector3& p);
您不想继续建立在第一个地方复制的对象。
这是在C ++中的良好做法取决于两件事情上,你是否希望你的对象可复制(即分配给另一个变量),或者不这样做。如果你需要同时提供赋值运算符和拷贝构造函数。例如:
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;
的赋值运算符将被调用。
希望有所帮助。
在“按值传递”,因为你在你的操作者定义=,类型的副本被使用的做出本地值的方法。您的运营商不会被调用,因为系统无法找到一个构造器是需要的Vector3 - 您已经定义了一个拷贝构造函数,它的Vector3&
因此,正如其他人所说,你想要做的是定义你的运营商=如服用
const vector3& p
您也应该更新您的声明拷贝构造函数取常量的Vector3也。