简体   繁体   English

在C ++中永远不会调用重载运算符

[英]Overloaded operator is never called in C++

I'm writing a math library as a practical exercise. 我正在写一个数学库作为练习。 I've run into some problems when overloading the = operator. 重载=运算符时,我遇到了一些问题。 When I debuged it, I noticed that the call to vertex1 = vertex2 calls the copy constructor instead. 当我调试它时,我注意到对vertex1 = vertex2的调用改为调用了复制构造函数。

In the header file I have: 在头文件中,我有:

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

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

In the source file I implemented: 在源文件中,我实现了:

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

Later on I have a crossproduct method, and I want to use it like so: 稍后我有一个叉积方法,我想这样使用它:

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

The error message is: error: no matching function for call to `vector3::vector3(vector3)' but I do not want to call the copy constructor. 错误消息是:错误:没有匹配的函数来调用`vector3 :: vector3(vector3)',但是我不想调用复制构造函数。

There are mistakes in your code. 您的代码中有错误。 Your copy-constructor must take a const& . 您的复制构造函数必须采用const& The reference will avoid making a copy (which you wouldn't be able to do, being the copy-constructor), and it should be const since you're not modifying it: 该参考将避免制作副本(您将无法复制,成为副本构造函数),并且它应该是const因为您没有对其进行修改:

vector3(const vector3&);

Temporary variables can be bound to const& , but cannot be bound to a mutable reference. 临时变量可以绑定到const& ,但不能绑定到可变引用。 That is, with your code you could do: 也就是说,使用您的代码,您可以执行以下操作:

vector3 a;
vector3 b(a);

but not: 但不是:

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

Additionally, your operator= is incorrect. 此外,您的operator=错误。 Like the copy-constructor, it should generally take a const& , but it should return a reference to this . 像copy-constructor一样,它通常应采用const&但应返回this的引用 That's how chaining works: 这就是链接的工作方式:

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

Returning a temporary is unorthodox, and doesn't accomplish anything. 返回一个临时值是非正统的,并且不会完成任何事情。 In your case, you could assign over and over and never change the value. 在您的情况下,您可以反复分配并且永远不要更改该值。 Weird : 奇怪

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

operator= needs to change this . operator=需要更改this

vector3( vector3 &v ); vector3(vector3&v);

That really should be vector3( const vector3 &v ); 那真的应该是vector3( const vector3 &v );

Since your return a temporary value, you must call a copy-constructor which takes a const reference. 由于返回的是一个临时值,因此必须调用采用const引用的copy-constructor。

I do not want to call the copy constructor. 我不想调用复制构造函数。

What you want is irrelevant. 您想要的与您无关。 You need a copy constructor here. 您在这里需要一个复制构造函数。 operator = doesn't get called in this situation, the copy constructor is. 在这种情况下,不会调用operator = ,而复制构造函数是。 Besides, the signature is wrong, it should be 此外,签名是错误的,应该是

vector3& operator =(vector3 const& other);

The argument may also be passed in by value (but this is an advanced trick …) but the return value really must be a non-const reference. 参数也可以按值传递(但这是一个高级技巧……),但是返回值确实必须是非常量引用。

(The signature of your copy constructor is also unconventional, see James' answer.) (您的副本构造函数的签名也不是常规的,请参阅James的回答。)

Make vector3 vector3::operator =(vector3 p) use references instead so you don't need to create a copy. 使vector3 vector3::operator =(vector3 p)改为使用引用,因此您无需创建副本。

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

You didn't want to create a copied object in the first place anyway. 无论如何,您根本不想创建复制的对象。

It is good practice in C++ to do one of two things depending on whether you want your object copyable (ie assignable to another variable) or not. 在C ++中,根据您是否希望对象可复制(即可分配给另一个变量)来执行以下两项操作之一是一种好习惯。 If you do you need to provide both the assign operator and the copy constructor. 如果需要,则需要同时提供assign运算符和副本构造函数。 For example: 例如:

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

If you don't want it copyable you can put the prototype of both the copy constructor and the assign operator in a private section and do not provide an implementation. 如果您不希望它可复制,则可以将复制构造函数和assign运算符的原型放在专用部分中,而不提供实现。 Any attempt to copy it then will give a compiler error. 任何尝试复制它的操作都会产生编译器错误。

Whenever you use this kind of code: 每当您使用这种代码时:

Point P = anotherP;

the copy constructor will be called. 复制构造函数将被调用。 If you use this type of code: 如果您使用这种类型的代码:

Point P;
P = anotherP;

the assign operator will be called. 分配运算符将被调用。

Hope that helps. 希望能有所帮助。

When you "pass by value", as you are in your definition of operator =, a copy of the type is made for use a as local value to the method. 当您按值传递时(如您在operator =的定义中一样),将创建该类型的副本以用作方法的局部值。 Your operator isn't being called because the system cannot find a contructor that takes vector3 -- you've defined a copy constructor that takes vector3&. 不会调用您的运算符,因为系统无法找到采用vector3&的构造函数-您已定义了采用vector3&的副本构造函数。

Therefore, as others have stated, what you want to do is define your operator = as taking 因此,正如其他人所述,您想要做的就是定义您的运算子=

const vector3& p

You should also update your declared copy constructor to take const vector3 also. 您还应该更新声明的副本构造函数以也采用const vector3。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM