鱼C论坛

 找回密码
 立即注册
查看: 1048|回复: 2

[已解决]C++,副本构造器不执行重载的"="

[复制链接]
发表于 2020-11-15 22:06:27 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
运行结果.png

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


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



最佳答案
2020-11-15 22:30:45
  1. #include <iostream>
  2. #include <string>

  3. class Myclass
  4. {
  5. public:
  6.     Myclass(int *p);
  7.     Myclass(const Myclass &rhs);
  8.     ~Myclass();
  9.        
  10.     Myclass &operator= (const Myclass &rhs);   
  11.     void print();
  12. private:
  13.     int *ptr;
  14. };


  15. Myclass::Myclass(int *p)
  16. {
  17.     std::cout << "进入主构造器" << std::endl;
  18.     ptr = p;
  19.     std::cout << "离开主构造器" << std::endl;
  20. }

  21. Myclass &Myclass::operator=(const Myclass &rhs)
  22. {
  23.     std::cout << "开始赋值号重载\n";
  24.     if(this != &rhs)
  25.     {
  26.         std::cout << "判断结果为两个实例不同\n";
  27.                 //问题出在这里,么有对 ptr进行检查,就直接delete。ptr没有初值的时候就会出错。
  28.                 if(ptr != NULL)
  29.                 {
  30.                         delete ptr;
  31.                         ptr = NULL;
  32.                 }
  33.         std::cout << "为第二个实例的指针设置新地址\n";
  34.                
  35.         ptr = new int;
  36.         *ptr = *rhs.ptr;
  37.     }
  38.     else
  39.     {
  40.         std::cout << "赋值号两边是同一个对象,赋值号不做处理!\n";
  41.     }
  42.        
  43.     std::cout << "结束赋值号重载" <<std::endl;
  44.        
  45.     return *this;
  46. }

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

  56. void Myclass::print()
  57. {
  58.     std::cout << *ptr << std::endl;
  59. }

  60. Myclass::~Myclass()
  61. {
  62.     std::cout << "进入析构器" << std::endl;
  63.     delete ptr;
  64.     std::cout << "离开析构器" << std::endl;
  65. }


  66. int main()
  67. {
  68.     Myclass object1(new int(1));
  69.     Myclass object2(new int(2));
  70.     object2 = object1;
  71.     object1.print();
  72.     object2.print();
  73.        
  74.     std::cout << "..............\n";
  75.        
  76.     Myclass object3(new int(3));
  77.         //在这里执行了非法指令,程序退出了。
  78.     Myclass object4 = object3;
  79.     object3.print();
  80.     object4.print();
  81.        
  82.        
  83.     std::cout << "..............\n";
  84.        
  85.     Myclass object5(new int(5));
  86.     object5 = object5;
  87.     object5.print();
  88.        
  89.     return 0;
  90. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-11-15 22:30:45 | 显示全部楼层    本楼为最佳答案   
  1. #include <iostream>
  2. #include <string>

  3. class Myclass
  4. {
  5. public:
  6.     Myclass(int *p);
  7.     Myclass(const Myclass &rhs);
  8.     ~Myclass();
  9.        
  10.     Myclass &operator= (const Myclass &rhs);   
  11.     void print();
  12. private:
  13.     int *ptr;
  14. };


  15. Myclass::Myclass(int *p)
  16. {
  17.     std::cout << "进入主构造器" << std::endl;
  18.     ptr = p;
  19.     std::cout << "离开主构造器" << std::endl;
  20. }

  21. Myclass &Myclass::operator=(const Myclass &rhs)
  22. {
  23.     std::cout << "开始赋值号重载\n";
  24.     if(this != &rhs)
  25.     {
  26.         std::cout << "判断结果为两个实例不同\n";
  27.                 //问题出在这里,么有对 ptr进行检查,就直接delete。ptr没有初值的时候就会出错。
  28.                 if(ptr != NULL)
  29.                 {
  30.                         delete ptr;
  31.                         ptr = NULL;
  32.                 }
  33.         std::cout << "为第二个实例的指针设置新地址\n";
  34.                
  35.         ptr = new int;
  36.         *ptr = *rhs.ptr;
  37.     }
  38.     else
  39.     {
  40.         std::cout << "赋值号两边是同一个对象,赋值号不做处理!\n";
  41.     }
  42.        
  43.     std::cout << "结束赋值号重载" <<std::endl;
  44.        
  45.     return *this;
  46. }

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

  56. void Myclass::print()
  57. {
  58.     std::cout << *ptr << std::endl;
  59. }

  60. Myclass::~Myclass()
  61. {
  62.     std::cout << "进入析构器" << std::endl;
  63.     delete ptr;
  64.     std::cout << "离开析构器" << std::endl;
  65. }


  66. int main()
  67. {
  68.     Myclass object1(new int(1));
  69.     Myclass object2(new int(2));
  70.     object2 = object1;
  71.     object1.print();
  72.     object2.print();
  73.        
  74.     std::cout << "..............\n";
  75.        
  76.     Myclass object3(new int(3));
  77.         //在这里执行了非法指令,程序退出了。
  78.     Myclass object4 = object3;
  79.     object3.print();
  80.     object4.print();
  81.        
  82.        
  83.     std::cout << "..............\n";
  84.        
  85.     Myclass object5(new int(5));
  86.     object5 = object5;
  87.     object5.print();
  88.        
  89.     return 0;
  90. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-11-17 13:53:43 | 显示全部楼层

谢谢兄弟,我看之前小甲鱼的视频好像没有让 ptr = NULL,所以懵了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-14 01:24

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表