赋值运算符重载的问题

问题遇到的现象和发生背景
class person{
    
public:
    person(int a)
    {
        m_p = new int(a);
     } 
     
     
     ~person()
    {
        if(m_p != NULL)
        {
            delete m_p;
            m_p = NULL; 
         } 
    } 
    
    
    int *m_p;
    
    void operator=(person p)
    {
        if(this->m_p != NULL)
        {
            delete this->m_p;
            this->m_p = NULL; 
        }
    
        this->m_p = new int(*p.m_p);
    }
};
void text1()
{
    
    person p1(10);
    person p2(20);
    p2 = p1;
    cout<<"p1.age="<<*p1.m_p<<endl;
    cout<<"p2.age="<<*p2.m_p<<endl;
}

img

cout<<"p1.age="<<*p1.m_p<<endl; 输出一串数字 而不是 10
void operator=(person p) 写成 void operator=(person & p) 就可以正常运行

传值 不是创建一份 p1 的复制品
复制的p1 中的m_p 的指向 也是堆区的那块空间
解引用赋值到 p2创建的空间上 ( this->m_p = new int(*p.m_p);)
为啥输出的不是10 而是随机数

对两种写法的 p2 = p1 语句分类讨论:

  1. void operator=(person p)
    首先调用的是(合成)复制构造函数, 也就是是你所说的创建一份 p1 的复制品(假设为temp_p1), 然后调用赋值构造函数 (void operator=(person temp_p1)) 进行传值, 因此 p2 的输出是正确的, 但是临时对象在赋值过后是要被销毁的, 而复制构造函数中传入的参数为 p1 的引用, 所以最后销毁的也就是 p1 这个对象, 所以读到的值是错的, 至于为什么还能读到数值就不清楚了, 希望有大佬看到后解答一下。

person(person const &p) // 产生临时对象所调用的复制构造函数
{
this->m_p = p.m_p;
}

  1. void operator=(person &p)
    不产生临时对象, 所以自然也就不会调用析构函数。

先去掉赋值语句打印看看内容。