C++类一般包括:构造函数,拷贝构造函数,赋值构造函数和析构函数四大函数。
#include <iostream>
#include <string.h>
using namespace std;
class MyString
{
public:
MyString(const char* str = NULL)
{
if(str == NULL)
{
m_data = new char[1];
m_data = '\0';
}
else
{
int len = strlen(str)+1;
m_data = new char[len];
strcpy(m_data,str);
}
}
MyString (const MyString& str)
{
if(&str!=this)
{
int len = strlen(str.m_data)+1;
delete[] m_data;
m_data = new char[len];
strcpy(m_data,str.m_data);
}
}
MyString& operator=(const MyString& str)
{
if(&str!=this)
{
int len = strlen(str.m_data)+1;
delete[] m_data;
m_data = new char[len];
strcpy(m_data,str.m_data);
}
return *this;
}
virtual ~MyString(){
if(m_data!=NULL)
{
delete[] m_data;
m_data = NULL;
}
}
private:
char *m_data;
};
在上面的赋值构造函数中,都是先delete m_data的存储空间,然后再调用new开辟空间。但是,如果此时空间不足,则导致异常,此时m_data是一个空指针,很容易造成程序奔溃。另一方面,我们希望尽管没有赋值成功,但希望m_data没有发生改变。
改进:
MyString& operator=(const MyString& str)
{
if(&str!=this)
{
MyString strTemp(str);
char * temp = strTemp.m_data;
strTemp.m_data = m_data;
m_data = temp;
}
return *this;
}
创建一个临时实例对象strTemp。m_data指向了strTemp.data, 而strTemp.data 指向了原来m_data的存储区域。
strTemp出了if就会自动调用析构函数,回收资源。而strTemp.m_data此时所指向的m_data的存储区域,也就是说m_data的内存区域会自动回收。
可以看到,如果临时对象创建不成功,也不会影响原来m_data的值。