拷贝构造、拷贝赋值和析构
c++中有Big Three三个特殊的函数,他们就是拷贝构造函数,拷贝赋值函数和析构函数。
那么什么被成为拷贝构造函数呢?和构造函数类似,拷贝构造函数是用来在初始化类的实例时所使用的函数,不过是以拷贝的方式, 把一个已经存在的类的对象赋值给另外一个对象。拷贝构造函数同构造函数一样,没有返回值。因为是同一个类的不同对象,所以在拷贝构造函数中,我们能够直接访问类中的私有成员变量。
如下这种做法是可以通过编译的:
MyString::MyString(const MyString& rStr)
{
m_data = new char[strlen(rStr.m_data) + 1];
strcpy(m_data, rStr.m_data);
}
但是下面这种做法则不能通过编译,原因就是这个拷贝构造函数的传入参数并不是同一个类的对象,而是另外一个类的对象,所以它的私有成员变量是不可访问的。
MyString::MyString(const OtherString& ostr)
{
m_data = new char[strlen(ostr.m_data) + 1];
strcpy(m_data, ostr.m_data);
}
拷贝赋值函数和赋值函数比较类似,需要通过重载操作符=来实现自己的拷贝赋值函数。在实现拷贝赋值函数的时候,需要注意的一点是:自引用的检查。
如下是我实现的一个MyString的拷贝赋值函数:
MyString& MyString::operator = (const MyString& rStr)
{
if (this == &rStr)//自引用检查
return *this;
delete[] m_data;
m_data = new char[strlen(rStr.m_data) + 1];
strcpy(m_data, rStr.m_data);
return this;
}
最后是析构函数。析构函数是在类的对象生命周期结束的时候所调用的函数。所以需要把类中通过Malloc或者new创建的内存地址释放掉,不然会导致内存泄漏,当工程项目比较大的时候,甚至会导致程序的崩溃。使用free来释放掉malloc函数分配的地址空间,delete来释放new分配地址空间。侯老师有提到,其实new函数内部就是先调用malloc函数给一个void指针分配一片内存空间,然后将类型强制转换为所要分配的类型,最后调用函数的构造函数。delete函数原理也类似。