复制语义,深层复制(C ++)

时间:2020-02-24 11:15:00

标签: c++ deep-copy

我在c ++中有复制语义的问题

这是我的代码

#include <iostream>

class DeepCopy
{
private:
    int *_myInt;

public:
    DeepCopy(int val)
    {
        _myInt = (int *)malloc(sizeof(int));
        *_myInt = val;
        std::cout << "resource allocated at address " << _myInt << std::endl;
    }
    ~DeepCopy()
    {
        free(_myInt);
        std::cout << "resource freed at address " << _myInt << std::endl;
    }
    DeepCopy(DeepCopy &source)
    {
        _myInt = (int *)malloc(sizeof(int)); // line 1 
        *_myInt = *source._myInt;  // line 2
        std::cout << "resource allocated at address " << _myInt << " with _myInt = " << *_myInt << std::endl;
    }
    DeepCopy &operator=(DeepCopy &source)
    {
        _myInt = (int *)malloc(sizeof(int));
        std::cout << "resource allocated at address " << _myInt << " with _myInt=" << *_myInt << std::endl;
        *_myInt = *source._myInt;
        return *this;
    }
    void printOwnAddress() { std::cout << "Own address on the stack is " << this << std::endl; }
    void printMemberAddress() { std::cout << "Managing memory block on the heap at " << _myInt << std::endl << std::endl; }

};

int main()
{
    DeepCopy source(42);
    source.printOwnAddress();
    source.printMemberAddress();
    DeepCopy dest1(source);
    dest1.printOwnAddress();
    dest1.printMemberAddress();

    source.printOwnAddress();
    source.printMemberAddress();
    return 0;
}

真正的结果是在终端:

resource allocated at address 0x2511c20
Own address on the stack is 0x7ffdf539da00
Managing memory block on the heap at 0x2511c20

resource allocated at address 0x2512050 with _myInt = 42
Own address on the stack is 0x7ffdf539da10
Managing memory block on the heap at 0x2512050

Own address on the stack is 0x7ffdf539da00
Managing memory block on the heap at 0x2511c20

resource freed at address 0x2512050
resource freed at address 0x2511c20

让我们看看DeepCopy(DeepCopy&source)

据我所知

  1. 第1行,它获得_myInt的新内存,

  2. 第2行,在获得第1行的内存中分配源的_myInt

所以,我希望得到这样的结果

resource allocated at address 0x2511c20
Own address on the stack is 0x7ffdf539da00
Managing memory block on the heap at 0x2511c20

resource allocated at address 0x2512020 with _myInt = 42
Own address on the stack is 0x7ffdf539da10
Managing memory block on the heap at 0x2512020

Own address on the stack is 0x7ffdf539da00
Managing memory block on the heap at 0x2512050

resource freed at address 0x2512020
resource freed at address 0x2511c50

由于DeepCopy(DeepCopy&source)函数更改了源的成员地址,而不是目标的成员地址

但是,它与上面的实际结果不同。

我误会了什么?

1 个答案:

答案 0 :(得分:1)

source._myInt指向0x2511c20,在复制之前在之前。那没有改变。复制前后,dest1._myInt指向0x2512050。这两个指针不变,也不应改变。

存储在那些内存位置的数据将被复制,但指针本身不会被复制。

如果我们为您绘制出来,也许更容易理解:

首先,您创建source对象:

DeepCopy source(42);

创建类似这样的内容

+---------------+     +----------------+
| source._myInt | --> | 42 @ 0x2511c20 |
+---------------+     +----------------+

然后您创建dest1对象:

DeepCopy dest1(source);

如果我们逐步了解复制构造函数,那么我们首先有

_myInt = (int *)malloc(sizeof(int)); // line 1 

这使您拥有

+--------------+     +----------------+
| dest1._myInt | --> | ?? @ 0x2512050 |
+--------------+     +----------------+

[此时的值是不确定]

然后复制 value

*_myInt = *source._myInt;  // line 2

现在你有

+--------------+     +----------------+
| dest1._myInt | --> | 42 @ 0x2512050 |
+--------------+     +----------------+

最后,我们回到了main函数中,您将拥有:

+---------------+     +----------------+
| source._myInt | --> | 42 @ 0x2511c20 |
+---------------+     +----------------+

+--------------+     +----------------+
| dest1._myInt | --> | 42 @ 0x2512050 |
+--------------+     +----------------+

您有两个不同的对象,每个对象都有各自不同的_myInt变量,每个变量都指向不同的内存位置。这些位置的值恰好是相同的,但是指向这些值的 pointers 不同。

相关问题