为什么进行赋值不会使对象指向相同的位置

时间:2015-05-15 17:18:27

标签: c++ pointers copy-constructor

我试图理解复制构造函数的概念。使用复制构造函数我得到了理想的结果。但是使用复制构造函数我得到相同的结果。代码在这里给出:

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

它会调用复制构造函数吗?如果没有,为什么在这种情况下结果是相同的?

3 个答案:

答案 0 :(得分:2)

C ++区分对象引用到对象。如果你想要

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

Point& p2 = p1;

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

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

您的代码Point p2 = p1将调用此副本构造函数。

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

答案 1 :(得分:2)

  

但是如果没有复制构造函数,我会得到相同的结果。

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

  

不应该[光输出]是......

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

您需要使用指针或引用来获取所需的行为:

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

现在p2表现为p1的“别名”,所以实际上有一个对象。

demo

答案 2 :(得分:0)

通常在同时向另一个对象声明和初始化对象或传递给函数时调用复制构造函数。第一个陈述的含义是:

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

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

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

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