营销型网站建设托管,app要有网站做基础,微信公众号编辑 导入wordpress,平面设计要素今天我们来总结一下#xff0c;之前所学C中所遇到的一些经典的问题。
第一个疑问是#xff1a; -什么时候需要重载赋值操作符 -编译器是否提供默认的赋值操作#xff1f;
解答#xff1a; *编译器为每个类默认重载了赋值操作符 *默认的赋值操作符仅完成了浅拷贝 *当…今天我们来总结一下之前所学C中所遇到的一些经典的问题。
第一个疑问是 -什么时候需要重载赋值操作符 -编译器是否提供默认的赋值操作
解答 *编译器为每个类默认重载了赋值操作符 *默认的赋值操作符仅完成了浅拷贝 *当需要进行深拷贝时就需要进行赋值操作符的重载 *赋值操作符与拷贝构造函数有相同的存在意义。
下面我们还是给出一个例子程序来分析
#include iostream
#include stringusing namespace std;class Test
{int* m_pointer;
public:Test(){m_pointer NULL;}Test(int i){m_pointer new int[i];}void print(){cout m_pointer m_pointer endl;}~Test(){delete m_pointer;}
};int main()
{Test t1 1;Test t2;//t2 t1t1.print();t2.print();return 0;
}
上面这个程序运行结果为 上面的程序很简单我就不多分析了如果我想将以上的程序注释掉的那一行t2 t1取消注释加上呢运行结果如下 可以看出运行结果崩溃出现了内存错误。 是什么原因呢 由于我们让t2的堆空间指向了t1那么再释放堆空间的时候就需要释放两次可是我只有一个堆空间释放两次肯定要出现内存错误的。
下面我们给出解决办法进行深拷贝
#include iostream
#include stringusing namespace std;class Test
{int* m_pointer;
public:Test(){m_pointer NULL;}Test(int i){m_pointer new int(i);}Test(const Test obj) //深拷贝函数的构造{m_pointer new int(*obj.m_pointer);//先申请一个int型的堆空间然后给堆空间里加值//这个值是obj这个对象所指的m_pointer指针所指的值//然后让m_pointer再指向这个值的堆空间}Test operator (const Test obj) //重载赋值操作符返回类型必须是引用类型//参数必须是const类型的{if( this ! obj ) //防止自赋值当前对象的地址与传进来的参数的地址不一样{delete m_pointer;m_pointer new int(*obj.m_pointer);}return *this; //返回当前对象的值}void print(){cout m_pointer hex m_pointer endl;}~Test(){delete m_pointer;}
};int main()
{Test t1 1; //Test类对象t1内部的指针m_pointer执指向的堆空间的值为1Test t2; //Test类对象t2内部的指针m_pointer执指向的堆空间为空t2 t1; //因为要实现给t2一个单独的堆空间也就是实现深拷贝所以需要上面的赋值操作符的重载以及构造一个拷贝构造函数t1.print(); //打印的是堆空间的地址值16进制t2.print();return 0;
}运行结果为
以上程序的分析已经在程序的注释里面了已经说得很清楚。
总结 一般性原则 在需要进行深拷贝的时候必须进行赋值操作符的重载。 赋值操作符与拷贝构造函数有同等重要的意义。
任何文字的说明都无法比真正的代码能让你更加明白其中的原理多动手写~
想一起探讨以及获得各种学习资源加我有我博客中写的代码的原稿 qq1126137994 微信liu1126137994 可以共同交流关于嵌入式操作系统C语言C语言数据结构等技术问题。