为什么做赋值不会使对象指向同一位置

Why doing assignment does not make objects to point same location

我正在尝试理解复制构造函数的概念。使用复制构造函数,我得到了想要的结果。但是没有复制构造函数,我得到了相同的结果。代码在这里:

#include<iostream>
using namespace std;

class Point
{
private:
    int x, y;
public:
    Point(int x1, int y1) { x = x1; y = y1; }

    // Copy constructor
    // Point(const Point &p2) {x = p2.x; y = p2.y; }
    void set()
    {
        x=50;
        y = 100;
    }
    int getX()            {  return x; }
    int getY()            {  return y; }
};

int main()
{
    Point p1(10, 15); // Normal constructor is called here
    Point p2 = p1 ;
    // p2 = p1;
    cout << "p1.x = " << p1.getX() << ", p1.y = " << p1.getY();
    cout << "\np2.x = " << p2.getX() << ", p2.y = " << p2.getY();
    p2.set();
    cout << "\np1.x = " << p1.getX() << ", p1.y = " << p1.getY();
    cout << "\np2.x = " << p2.getX() << ", p2.y = " << p2.getY();
     // Copy constructor is called here

    // Let us access values assigned by constructors
    return 0;
}

输出是:

p1.x = 10, p1.y = 15
p2.x = 10, p2.y = 15
p1.x = 10, p1.y = 15
p2.x = 50, p2.y = 100

不应该是:

p1.x = 10, p1.y = 15
p2.x = 10, p2.y = 15
p1.x = 50, p1.y = 100
p2.x = 50, p2.y = 100

编辑 1:如果我像这样初始化对象会怎样:

Point p1(10, 15); // Normal constructor is called here
    Point p2(11,10);
    p2 = p1;

会调用拷贝构造函数吗?如果不是,为什么在这种情况下结果是一样的?

C++ 对对象的 objectsreferences 进行了区分。如果你想要

p2p1 指向相同的 Point,你应该这样做:

Point& p2 = p1;

因为您从未为您的 Point class 定义复制构造函数,编译器给了您一个。它实际上看起来像这样:

Point(const Point& other) : x(other.x), y(other.y)
{}

而您的代码 Point p2 = p1 将调用此复制构造函数。

这会导致整数值被复制,而不是指向内存中的相同位置。

But without copy constructor I get the same result.

这是因为您获得了编译器为您插入的默认复制构造函数和默认赋值运算符。它与您手写的复制构造函数所做的完全相同,因此无需手动编写代码。

Shouldn't it [the optput] be ...

不,不应该。在您的代码中 p1p2 是不同的不相关对象,即使 p2 的初始状态来自 p1.

您需要使用指针或引用来获得您想要的行为:

// Point p2 = p1;
Point& p2(p1);

现在 p2 表现为 p1 的 "alias",因此实际上只有一个对象。

demo

复制构造函数通常在声明和初始化对象同时到另一个对象的情况下,或者在传递给函数时被调用。第一条语句的意思是:

Point p1(10,15);
Point p2(p1);

是复制构造函数的用法示例 while,

Point p1(10,15);
Point p2;
p2=p1;

只是简单的赋值。 不,您的输出在第一种情况下是正确的。复制构造函数只是将一个对象的值复制到另一个对象中,它不会使新对象成为引用对象。 此外,复制构造函数的主要用途通常是在函数中。 作为脚注,要了解构造函数和调用它们的时间,您可以在其中使用不同的 cout 语句。然后您就会知道何时调用了特定的构造函数。 P.S。我是初学者,如果有什么不对的地方请告诉我。