spenser 发表于 2020-11-15 22:06:27

C++,副本构造器不执行重载的"="



代码如下,请大神帮忙分析一下是什么情况


#include <iostream>
#include <string>

class Myclass
{
public:
    Myclass(int *p);
    Myclass(const Myclass &rhs);
    ~Myclass();

    Myclass &operator= (const Myclass &rhs);   
    void print();
private:
    int *ptr;
};


Myclass::Myclass(int *p)
{
    std::cout << "进入主构造器" << std::endl;
    ptr = p;
    std::cout << "离开主构造器" << std::endl;
}

Myclass &Myclass::operator=(const Myclass &rhs)
{
    std::cout << "开始赋值号重载\n";
    if(this != &rhs)
    {
      std::cout << "判断结果为两个实例不同\n";
      delete ptr;                        
      std::cout << "为第二个实例的指针设置新地址\n";

      ptr = new int;
      *ptr = *rhs.ptr;
    }
    else
    {
      std::cout << "赋值号两边是同一个对象,赋值号不做处理!\n";
    }

    std::cout << "结束赋值号重载" <<std::endl;

    return *this;
}

Myclass::Myclass(const Myclass &rhs)
{
    std::cout << "进入副本构造器\n";
    *this = rhs;
    std::cout << "离开副本构造器\n";
}

void Myclass::print()
{
    std::cout << *ptr << std::endl;
}

Myclass::~Myclass()
{
    std::cout << "进入析构器" << std::endl;
    delete ptr;
    std::cout << "离开析构器" << std::endl;
}


int main()
{
    Myclass object1(new int(1));
    Myclass object2(new int(2));
    object2 = object1;
    object1.print();
    object2.print();

    std::cout << "..............\n";

    Myclass object3(new int(3));
    Myclass object4 = object3;
    object3.print();
    object4.print();


    std::cout << "..............\n";

    Myclass object5(new int(5));
    object5 = object5;
    object5.print();

    return 0;
}



xieglt 发表于 2020-11-15 22:30:45

#include <iostream>
#include <string>

class Myclass
{
public:
    Myclass(int *p);
    Myclass(const Myclass &rhs);
    ~Myclass();
       
    Myclass &operator= (const Myclass &rhs);   
    void print();
private:
    int *ptr;
};


Myclass::Myclass(int *p)
{
    std::cout << "进入主构造器" << std::endl;
    ptr = p;
    std::cout << "离开主构造器" << std::endl;
}

Myclass &Myclass::operator=(const Myclass &rhs)
{
    std::cout << "开始赋值号重载\n";
    if(this != &rhs)
    {
      std::cout << "判断结果为两个实例不同\n";
                //问题出在这里,么有对 ptr进行检查,就直接delete。ptr没有初值的时候就会出错。
                if(ptr != NULL)
                {
                        delete ptr;
                        ptr = NULL;
                }
      std::cout << "为第二个实例的指针设置新地址\n";
               
      ptr = new int;
      *ptr = *rhs.ptr;
    }
    else
    {
      std::cout << "赋值号两边是同一个对象,赋值号不做处理!\n";
    }
       
    std::cout << "结束赋值号重载" <<std::endl;
       
    return *this;
}

Myclass::Myclass(const Myclass &rhs)
{       
        //这里需要给 ptr 赋初值
        ptr = NULL;
    std::cout << "进入副本构造器\n";
        //因为ptr 没有初值,进入 = 函数后直接delete ptr 导致错误。
    *this = rhs;
    std::cout << "离开副本构造器\n";
}

void Myclass::print()
{
    std::cout << *ptr << std::endl;
}

Myclass::~Myclass()
{
    std::cout << "进入析构器" << std::endl;
    delete ptr;
    std::cout << "离开析构器" << std::endl;
}


int main()
{
    Myclass object1(new int(1));
    Myclass object2(new int(2));
    object2 = object1;
    object1.print();
    object2.print();
       
    std::cout << "..............\n";
       
    Myclass object3(new int(3));
        //在这里执行了非法指令,程序退出了。
    Myclass object4 = object3;
    object3.print();
    object4.print();
       
       
    std::cout << "..............\n";
       
    Myclass object5(new int(5));
    object5 = object5;
    object5.print();
       
    return 0;
}

spenser 发表于 2020-11-17 13:53:43

xieglt 发表于 2020-11-15 22:30


谢谢兄弟{:5_106:},我看之前小甲鱼的视频好像没有让 ptr = NULL,所以懵了
页: [1]
查看完整版本: C++,副本构造器不执行重载的"="