C++ 复制语义,深度复制(C+;+;)

C++ 复制语义,深度复制(C+;+;),c++,deep-copy,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 a

我对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;
}
让我们看看DeepCopy(DeepCopy&source)

据我了解,

  • 第1行,它为_myInt获取新内存

  • 第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)更改了源的成员地址,而不是目标的地址

    然而,这与上述实际结果不同


    我误解了什么?

    来源。_myInt
    指向复制前后的
    0x2511c20
    。这并没有改变
    dest1._myInt
    在复制之前和之后指向
    0x251250
    。这两个指针不会改变,也不应该改变

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

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

    首先创建
    对象:

    DeepCopy source(42);
    
    DeepCopy dest1(source);
    
    这就产生了这样的结果:

    +---------------+ +----------------+ | source._myInt | --> | 42 @ 0x2511c20 | +---------------+ +----------------+ 如果我们一步一步地遍历复制构造函数,我们首先

    _myInt = (int *)malloc(sizeof(int)); // line 1 
    
    这导致你有

    +--------------+ +----------------+ | dest1._myInt | --> | ?? @ 0x2512050 | +--------------+ +----------------+ 现在你有了

    +--------------+ +----------------+ | dest1._myInt | --> | 42 @ 0x2512050 | +--------------+ +----------------+
    您有两个不同的对象,每个对象都有各自不同的
    \u myInt
    变量,每个变量指向不同的内存位置。这些位置中的值恰好相同,但指向这些值的指针不同。

    赋值运算符有三个问题:首先是内存泄漏,因为您从未释放现有内存;其次,在初始化该值之前取消引用
    \u myInt
    ;最后,您不检查自我分配。未调用分配运算符。实际输出是正确的,并且您的期望似乎是错误的。为什么你认为对象应该交换指针?有问题的行
    *\u myInt=*源代码。\u myInt
    正在将值从
    *源复制到
    *\u myInt
    中。谢谢您的评论,我误解了它也复制了地址。
    *_myInt = *source._myInt;  // line 2
    
    +--------------+ +----------------+ | dest1._myInt | --> | 42 @ 0x2512050 | +--------------+ +----------------+ +---------------+ +----------------+ | source._myInt | --> | 42 @ 0x2511c20 | +---------------+ +----------------+ +--------------+ +----------------+ | dest1._myInt | --> | 42 @ 0x2512050 | +--------------+ +----------------+