小记:静默如初,安之若素
1. 拷贝构造
1. 浅拷贝和深拷贝
1)定义:如果一个类中包含指针形式的成员变量,用缺省的拷贝构造函数只是复制指针变量本身,而没有复制指针所指向的内容,这种拷贝方式成为浅拷贝。
2)浅拷贝将会导致不同对象间的数据共享,同时会在析构函数中引发”double free“异常,因此就必须自己定义一个支持复制指针内容的拷贝构造函数,即深拷贝.
2 using namespace std;
3
4 class Integer
5 {
6 public:
7 Integer(int data = 0)
8 :m_data(new int(data))
9 {
10 //m_data = new int(data);
11 }
12 ~Integer(void)
13 {
14 cout<<"xigou hanshu"<<endl;
15 delete m_data;
16 }
17 //Integer i2(i1)
18 //i2.m_data = i1.m_data
19 //缺省的拷贝构造函数(浅拷贝)
20 /*Integer(const Integer& that)
21 {
22 m_data = that.m_data;
23 }*/
24
25 //Integer i2(i1);
26 //i2.data = new int(*i1.m_data);
27 //自定义深拷贝构造
28 Integer(const Integer &that)
29 {
30 m_data = new int(*that.m_data);
31 }
32
33 void print(void) const
34 {
35 cout << *m_data << std::endl;
36 }
37
38 private:
39 int *m_data;//指针一定要注意最后释放,否则造成内存泄露
40 };
41
42 int main(int argc, char *argv[])
43 {
44 Integer i1(100);
45 Integer i2(i1);//拷贝构造
46
47 i1.print();
48 i2.print();
49
50 return 0;
51 }
笔试题/练习:实现string类
1 #include <iostream>
2 #include <cstring>
3 using namespace std;
4 class String
5 {
6 public:
7 //构造函数
8 String(const char *str = "")//缺省
9 {
10 m_str = new char[strlen(str) + 1];
11 strcpy(m_str, str);
12 }
13 //析构函数
14 ~String(void)
15 {
16 delete[] m_str;
17 }
18 //拷贝构造函数
19 //浅拷贝
20 //String (const String &that)
21 //{
22 // m_str = that.m_str;
23 //}
24
25 //深拷贝
26 String (const String &that)
27 {
28 m_str = new char[strlen(that.m_str) + 1];
29 strcpy(m_str, that.m_str);
30 }
31 private:
32 char *m_str;
33 public:
34 const char *c_str()const
35 {
36 return m_str;
37 }
38 };
39 int main(int argc, char* argv[])
40 {
41 String s1 = "hello world!";
42 cout << s1.c_str() << endl;
43 String s2 = s1;
44 cout << s2.c_str() << endl;
45 return 0;
46 }
2. 拷贝赋值
1)当编译器看到两个对象的赋值操作时,比如” i3=i2 “,会将其翻译成函数调用形式: ”i3.operator = (i2)“,该函数成为拷贝赋值操作符函数,由该函数完成两个对象的复制的过程。
2)缺省的拷贝赋值函数和缺省拷贝构造函数类型,也是浅拷贝,有**”double free“问题和内存泄露**问题;
3)所以必须自己定义支持深拷贝的拷贝赋值操作符函数;
4)语法:
类名 & operator=(const 类名& that)
{
if(&that != this)//防止自赋值
{
//释放旧资源
//分配新资源(大小与新数据大小相同)
//拷贝新数据
}
return *this;//返回自引用
}
#include<iostream>
2 using namespace std;
3
4 class Integer
5 {
6 public:
7 Integer(int data = 0)
8 :m_data(new int(data))
9 {
10 //m_data = new int(data);
11 }
12 ~Integer(void)
13 {
14 cout<<"xigou hanshu"<<endl;
15 delete m_data;
16 }
17 //Integer i2(i1)
18 //i2.m_data = i1.m_data
19 //缺省的拷贝构造函数(浅拷贝)
20 /*Integer(const Integer& that)
21 {
22 m_data = that.m_data;
23 }*/
24
25 //Integer i2(i1);
26 //i2.data = new int(*i1.m_data);
27 //自定义深拷贝构造
28 Integer(const Integer &that)
29 {
30 m_data = new int(*that.m_data);
31 }
32
33 void print(void) const
34 {
35 cout << *m_data << std::endl;
36 }
37
38 //i3 = i2;-->i3.operator=(i2)
39 //i3.m_data = i2.m_data
40 //类中缺省的拷贝赋值函数
41 /*Integer& operator=(const Integer& that)
42 {
43 cout <<" 拷贝赋值操作符函数" << endl;
44 m_data = that.m_data;
45 return *this;
46 }*/
47 //i3 = i2;==>i3.operator=(i2)
48 //*i3.m_data = *i2.m_data;
49 //自定义深拷贝赋值函数
50 Integer& operator=(const Integer &that)
51 {
52 if(&that != this)
53 {
54 delete m_data;
55 m_data = new int;
56 *m_data = *that.m_data;
57 }
58 return *this;
59 }
60 private:
61 int *m_data;//指针一定要注意最后释放,否则造成内存泄露
62 };
63
64 int main(int argc, char *argv[])
65 {
66 Integer i1(100);
67 Integer i2(i1);//拷贝构造
68
69 i1.print();
70 i2.print();
71
72 Integer i3;//i3(i2)-->拷贝构造
73 //i3.operator= (i2);
74 i3 = i2;//拷贝赋值,存在问题:double free,内存泄露
75 /*
76 eg:
77 int *i2 = new int(100);
78 int *i3 = new int(0);
79
80 i3 = i2;//i3原有的内存0泄露了,因为i3指向了i2
81 *i2-->100
82 *i3-->100
83
84 delete i2;
85 delete i3;
86 */
87 i3.print();
88
89 return 0;
90 }
笔试题/练习:实现string类
示例程序(拷贝构造和拷贝赋值):
1 #include <iostream>
2 #include <cstring>
3 using namespace std;
4 class String
5 {
6 public:
7 //构造函数
8 String(const char *str = "")//缺省
9 {
10 m_str = new char[strlen(str) + 1];
11 strcpy(m_str, str);
12 }
13 //析构函数
14 ~String(void)
15 {
16 delete[] m_str;
17 }
18 //拷贝构造函数
19 //浅拷贝
20 //String (const String &that)
21 //{
22 // m_str = that.m_str;
23 //}
24
25 //深拷贝
26 String (const String &that)
27 {
28 m_str = new char[strlen(that.m_str) + 1];
29 strcpy(m_str, that.m_str);
30 }
31 //拷贝赋值
32 //自定义深拷贝赋值操作函数
33 //s2==>hello
34 //s3==>hello world
35 //s2 = s3; ==>s2.operator(s3)
36 String& operator=(const String &that)
37 {
38 if(&that != this)//防止自赋值
39 {
40 delete[] m_str;//释放旧资源
41 m_str = new char[strlen(that.m_str)+1];//释放旧资源
42 strcpy(m_str, that.m_str);//拷贝新数据
43 }
44 return *this;//返回自引用
45 }
46 private:
47 char *m_str;
48 public:
49 const char *c_str()const
50 {
51 return m_str;
52 }
53 };
54 int main(int argc, char* argv[])
55 {
56 String s1 = "hello";
57 cout << s1.c_str() << endl;
58 String s2 = s1;
59 cout << s2.c_str() << endl;
60
61 String s3 = "hello world";
62 //s2.operator=(s3)
63 s2 = s3;//拷贝赋值
64 cout << s2.c_str() << endl;
65 return 0;
66 }