在C++中,编译器至少给一个类添加4个函数:默认构造函数、默认析构函数、默认拷贝构造函数、赋值运算符operator=,对属性进行赋值。系统默认的这些函数只进行浅拷贝,一旦对象有存放在堆区的数据成员,在析构函数中,就会发生重复释放同一片堆区内存空间的问题,导致程序崩溃,无法运行。
注意:如果想要实现链式编程,那么函数返回值类型就必须是对象的引用。如果函数返回值只是普通的数据类型,那么返回值只是一个由浅拷贝得来的副本,而无法对真正的数据进行操作。
#include <iostream>
#include <Windows.h>
using namespace std;
class MyInteger
{
private:
int* m_A;
public:
MyInteger();
MyInteger(int a);
~MyInteger() // 析构函数
{
if(m_A != NULL)
{
delete m_A; // 销毁数据在堆区的内存空间
m_A = NULL;
}
}
friend ostream& operator << (ostream& cout, MyInteger& myint);
// 重载赋值运算符
MyInteger& operator = (MyInteger& myint);
};
// 无参构造函数
MyInteger::MyInteger()
{
m_A = NULL;
}
// 有参构造函数
MyInteger::MyInteger(int a)
{
m_A = new int(a);
}
//全局函数重载左移运算符
ostream& operator << (ostream& cout, MyInteger& myint)
{
cout << *myint.m_A;
return cout;
}
// 重载赋值运算符
// 函数返回值类型是引用类型,这样可以实现链式编程
MyInteger& MyInteger::operator = (MyInteger& myint)
{
// 先释放指针变量,然后进行深拷贝
if (m_A != NULL)
{
delete m_A;
m_A = NULL;
}
m_A = new int(*myint.m_A); // 深拷贝,在堆区分配内存空间,m_A指向这片内存空间
// 返回函数所属类的对象
return *this;
}
int main(void)
{
MyInteger myint1(18);
MyInteger myint2(20);
MyInteger myint3(22);
myint3 = myint2 = myint1;
cout << myint3 << endl; // 输出18
system("pause");
return 0;
}