含有指针变量的类需要重写拷贝构造函数,拷贝赋值函数,析构函数
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
含有指针变量的类需要重写拷贝构造函数,拷贝赋值函数,析构
函数
编译器⾃带拷贝构造(ctor)和拷贝赋值函数(operator =),但是对于成员变量含有指针的类,其不能使⽤默认的拷贝赋值函数。
因为使⽤默认的,会直接将指针指向的地址进⾏赋值 (浅拷贝,共享内存,共指⼀个对象),⽽不是分配⼀块内存,具有相同的数值 (深拷贝,独⽴,两个对象)。
浅拷贝容易造成dangling pointer。
⽤⼀个例⼦来展⽰:
1 #ifndef __MYSTRING__
2#define __MYSTRING__
3
4class String{
5public:
6 String(const char* cstr=0);
7 String(const String& str); // 拷贝构造
8 String& operator= (const String& str); // 拷贝赋值
9 ~String();
10char* get_c_str const(){
11return m_data;
12 }
13private:
14char* m_data; // 带指针成员的类:⼀定要注意拷贝赋值,拷贝构造,析构
15// String的底部通过char实现,在外部表现为string
16 };
17
18 inline String::String ( const char* cstr=0 ){
19if(cstr){
20 m_data=new char[strlen(cstr)+1];
21 strcpy(m_data,cstr); // char * strcpy ( char * destination, const char * source );
22 }
23else{ // 考虑cstr=0;
24 m_data=new char[1];
25 m_data[0]='\0';
26 }
27 }
28
29 inline String::String(const String& str){
30 m_data=new char[strlen(str.get_c_str())+1];
31 strcpy(m_data,str.m_data);
32 }
33
34 inline String::~String(){
35delete[] m_data;
36 }
37
38 inline String& String::operator=(const String& str){
39if(this==&str){ // self assignment :⾃我检验(如果没有进⾏这样的处理,在⾃我赋值会产⽣严重的错误)
40return *this;
41 }
42// 构造函数是第⼀次,因此不需要删除,但是赋值需要先进⾏delete
43delete[] m_data; // 先删除,重新分配⼀样⼤⼩!
44 m_data=new char[strlen(str.get_c_str())+1];
45 strcpy(m_data,str.m_data);
46return *this; // 其实不⽤返回*this也可以,因为已经实现了修改,但是这样有⼀个好处可以实现 a=b=c;(因为返回的类型继续⽀持=)
47 }
48
49// 调⽤形式: cout << String() ; 第⼀个参数为 << 左边,第⼆个参数为 << 右侧;返回ostream 可以实现 cout << a << b ;
50 ostream& operator<<(ostream& os,const String& str){
51 os<<str.get_c_str();
52return os;
53 }
54
55#endif。