一个类里面有6个默认的函数:
1.构造函数: Test t;
2.拷贝构造函数: Test t1 = t;
3.赋值函数: Test t2; t2 = t1;
4.析构函数;
5.对一般对象的取地址函数: Test t3; Test *pt = &t3; //Test *pt = t3.operator&();
既然系统已经有默认的函数,那还要写吗?
调用默认的拷贝构造函数(赋值函数)只拷贝(赋值)指针
所以s1和s2会指向相同的空间,当s2析构后,该空间被释放,当s1析构时则发生错误
所以浅拷贝无法完成我们的任务;所以需要重写拷贝构造函数(赋值函数),进行深拷贝,这样将
不再只进行指针拷贝,还要创建空间,进行值拷贝,这样就可以解决同一块空间释放多次的问题;
重新写赋值函数时,需要注意将对象之前指向的空间进行释放,
否则会发生内存泄漏;
所以,如果类中的数据成员包含指针,需要重新编写拷贝构造函数和赋值函数,因为这两个函数会
导致浅拷贝,浅赋值的问题。
赋值函数书写四部曲:
1.判断是否为自己给自己赋值;
2.释放原有空间;
3.申请新空间进行赋值;
4.返回自身对象
1.构造函数: Test t;
2.拷贝构造函数: Test t1 = t;
3.赋值函数: Test t2; t2 = t1;
4.析构函数;
5.对一般对象的取地址函数: Test t3; Test *pt = &t3; //Test *pt = t3.operator&();
6.对常对象的取地址函数 : const Test t4; const Test *pt = &t4;
<span style="font-size:18px;">class Test
{
public:
//构造函数
Test(int d = 0):data(d)
{
}
//拷贝构造函数
Test(const Test &t)
{
data = t.data;
}
//赋值函数
Test& operator=(const Test &t)
{
if(this != &t)
{
data = t.data;
}
}
//析构函数
~Test()
{
}
public:
//对一般对象的取址函数
Test* operator&()
{
return this;
}
//对常对象的取地址函数
const Test* operator&()const
{
return this;
}
private:
int data;
};</span>
既然系统已经有默认的函数,那还要写吗?
<span style="font-size:18px;">举例:
class String
{
public:
String(const char *str = "")
{
if(str == NULL)
{
data = (char *)malloc(sizeof(char));
data[0] = '\0';
}
else
{
data = (char *)malloc(sizeof(char)*(strlen(str)+1));
strcpy(data,str);
}
}
String(const String &s)
{
data = (char *)malloc(sizeof(char)*(strlen(s.data)+1));
strcpy(data,s.data);
}
Stirng& operator=(const String &s)
{
if(this != &s)
{
free(data);
data = NULL;
data = (char *)malloc(sizeof(char)*(strlen(s.data)+1));
strcpy(data,s.data);
}
return *this;
}
~String()
{
free(data);
data = NULL;
}
private:
char *data;
}
int main()
{
char *str = "Hello";
String s1(str);
String s2(s1); //当调用默认的拷贝构造函数时,只进行浅拷贝,即只拷贝了指针,所以要编写新的拷贝构造函数
String s3;
s3 = s2; //当调用默认的赋值函数是,只进行浅赋值,即只赋值了指针,所以要编写新的赋值函数
}</span>
调用默认的拷贝构造函数(赋值函数)只拷贝(赋值)指针
所以s1和s2会指向相同的空间,当s2析构后,该空间被释放,当s1析构时则发生错误
所以浅拷贝无法完成我们的任务;所以需要重写拷贝构造函数(赋值函数),进行深拷贝,这样将
不再只进行指针拷贝,还要创建空间,进行值拷贝,这样就可以解决同一块空间释放多次的问题;
重新写赋值函数时,需要注意将对象之前指向的空间进行释放,
否则会发生内存泄漏;
所以,如果类中的数据成员包含指针,需要重新编写拷贝构造函数和赋值函数,因为这两个函数会
导致浅拷贝,浅赋值的问题。
赋值函数书写四部曲:
1.判断是否为自己给自己赋值;
2.释放原有空间;
3.申请新空间进行赋值;
4.返回自身对象