既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
}
编译并执行上述代码,结果如下:
![](https://img-blog.csdn.net/20180611184315643?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpaXRkYXI=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
通过上述结果能够知道:通过使用默认的赋值运算符“=”,可以让对象 obj2 中的所有数据成员的值与对象 obj1 相同。这种情况下,编译系统提供的默认赋值运算符可以正常使用。
但是,在下面的示例中,使用编译系统提供的默认赋值运算符,就会出现问题了。
示例代码内容如下:
#include
#include <string.h>
using namespace std;
class ClassA
{
public:
ClassA()
{
}
ClassA(const char* pszInputStr)
{
pszTestStr = new char[strlen(pszInputStr) + 1];
strncpy(pszTestStr, pszInputStr, strlen(pszInputStr) + 1);
}
virtual ~ClassA()
{
delete pszTestStr;
}
public:
char* pszTestStr;
};
int main()
{
ClassA obj1(“liitdar”);
ClassA obj2;
obj2 = obj1;
cout << "obj2.pszTestStr is: " << obj2.pszTestStr << endl;
cout << "addr(obj1.pszTestStr) is: " << &obj1.pszTestStr << endl;
cout << "addr(obj2.pszTestStr) is: " << &obj2.pszTestStr << endl;
return 0;
}
编译并运行上述代码,结果如下:
![](https://img-blog.csdn.net/20180611190943392?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpaXRkYXI=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
上述错误信息表明:当对象 obj1 和 obj2 进行析构时,由于重复释放了同一块内存空间,导致程序崩溃报错。在这种情况下,就需要我们重载赋值运算符“=”了。
## 2 示例代码
### 2.1 示例代码1
我们修改一下上面出错的示例代码,编写一个包含赋值运算符重载函数的类,修改后的代码内容如下:
#include
#include <string.h>
using namespace std;
class ClassA
{
public:
ClassA()
{
}
ClassA(const char* pszInputStr)
{
pszTestStr = new char[strlen(pszInputStr) + 1];
strncpy(pszTestStr, pszInputStr, strlen(pszInputStr) + 1);
}
virtual ~ClassA()
{
delete pszTestStr;
}
// 赋值运算符重载函数
ClassA& operator=(const ClassA& cls)
{
// 避免自赋值
if (this != &cls)
{
// 避免内存泄露
if (pszTestStr != NULL)
{
delete pszTestStr;
pszTestStr = NULL;
}
pszTestStr = new char[strlen(cls.pszTestStr) + 1];
strncpy(pszTestStr, cls.pszTestStr, strlen(cls.pszTestStr) + 1);
}
return *this;
}
public:
char* pszTestStr;
};
int main()
{
ClassA obj1(“liitdar”);
ClassA obj2;
obj2 = obj1;
cout << "obj2.pszTestStr is: " << obj2.pszTestStr << endl;
cout << "addr(obj1.pszTestStr) is: " << &obj1.pszTestStr << endl;
cout << "addr(obj2.pszTestStr) is: " << &obj2.pszTestStr << endl;
return 0;
}
编译并运行上述代码,结果如下:
![](https://img-blog.csdn.net/20180611192042370?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2xpaXRkYXI=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
通过上述结果能够看到,利用赋值运算符重载函数,解决了对象赋值时,析构函数多次释放同一块内存空间的问题。
对于上述代码,有以下几点需要说明:
* 当为一个类的对象赋值(可以用本类对象为其赋值,也可以用其它类型的值为其赋值)时,该对象(如本例的 obj2)会调用该类的赋值运算符重载函数,进行具体的赋值操作。如上述代码中的“obj2 = obj1;”语句,用 obj1 为 obj2 赋值,obj2 会调用 ClassA 类的赋值运算符重载函数;
* 下方语句和语句“ClassA obj2 = obj1;”在调用函数时是有区别的:前者第一句是对象 obj2 的声明及定义,调用类 ClassA 的无参构造函数,所以“obj2 = obj1;”一句是在对象 obj2 已经存在的情况下,用 obj1 来为 obj2 赋值,调用的是赋值运算符重载函数;而后者,是用 obj1 来初始化 obj2,调用的是拷贝构造函数。拷贝构造函数的语句样式为“ClassA(const ClassA& cls)”。关于拷贝构造函数的详细知识,请查询相关内容,此处不展开介绍;
ClassA obj2;
obj2 = obj1;
* 当程序没有显式地提供一个以“本类或本类的引用”为参数的赋值运算符重载函数时,编译器会自动生成一个默认的赋值运算符重载函数(即默认赋值运算符)。
### **2.2 示例代码2**
示例代码2内容如下:
#include
#include
using namespace std;
class Data
{
private:
int data;
public:
// 构造函数
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新