尽管通过引用传递,为什么我的运算符 + 重载会调用我的复制构造函数?

Why does my operator + overload call my copy constructor despite being passed by reference?

我已经做了一些研究,但我无法找到对我的代码行为的解释(我可能没有问正确的问题)。我正在使用 C++,使用 VS2019。

代码参考了数据结构和其他对象教科书中的 Points class。

我现在的 class:

class point {
private:
    double x;
    double y;
public:
    //constructors
    point(double ix = 0.0, double iy = 0.0) {
        x = ix;
        y = iy;
    }
    point(const point &z) {
        x = z.getX();
        y = z.getY();
        cout << "copy constructor triggered" << endl;
        cout << x << "," << y << endl;
    }

    //assignment
    void operator = (const point& result) {
        x = result.getX();
        y = result.getY();
        cout << "assignment overload triggered" << endl;
        cout << x << "," << y << endl;
    }

    //getters
    double getX() const {
        return x;
    }
    double getY() const{
        return y;
    }

    //setters
    void setX(double newX) {
        x = newX;
    }
    void setY(double newY) {
        y = newY;
    } //other function members are omitted
}//end point() class

point operator + (const point& A, const point& B) { //Adds x1 to x2, y1 to y2
    point n;

    n.setX(A.getX()+ B.getX());
    n.setY(A.getY()+ B.getY());
    return n;
}

当我发现无法在同一行上创建 class 的实例时出现问题,因为我试图使用 operator+ 重载添加两个实例。

point p1(5, 3);
point p2(12, 9);
point p3 = p1 + p2; //gives the following error: class "point" has no suitable copy constructor

我发现我犯了一个错误,忘记在我的复制构造函数中包含“const”。通过使用复制构造函数解决该问题,我能够使代码运行良好以提交我的作业,但我对我的理解并不满意。

在解决该问题的过程中,我还在 class 定义中添加了赋值运算符重载 (=)。 运行 通过一些控制台调试,我发现了一个奇怪的模式:

point p1(5, 3);
point p2(12, 9);
point p3;
p3 = p1 + p2; //calls both copy constructor and assignment instructor
point p4 = p1 + p2; // calls only copy constructor

point p5;
p5 = p1; //calls only assignment operator
point p6 = p2; // calls only copy constructor

所以现在,我想知道为什么p3 = p1 + p2 同时调用复制构造函数和赋值重载。 编译器在添加点时调用复制构造函数吗?我不认为这是因为 operator+ 重载使用默认构造函数创建一个临时点,然后使用 getter 和 setter 手动更改值,然后 returns 该临时点。我的理解是复制构造函数应该只在创建一个新对象时调用,而p3不是。

我还应该说我们还没有讨论使用指针 classes/objects。

在此感谢任何帮助。 在此先感谢您的帮助。

创建临时点并更改其值不会调用复制构造函数。

您在此处return创建对象,而不是对象的指针或引用:

point operator + (const point& A, const point& B) { //Adds x1 to x2, y1 to y2

当您 return 从您的函数中创建一个新对象时,您的函数内部的对象将被创建,这就是复制构造函数被调用的地方。