Constructors_Destructor_and_Assignment_Operators
1 //provision_7:Declare destructors virtal in polymorphic base classes
2 /*
3 只有当class 内含有至少一个virtual function 才为它声明virtual destructor
4 不声明 virtual:derived 成分没被销毁
5 没有虚函数时声明 virtual :增加对象体积
6 */
7
8 //provision_8:Prevent exceptions from leaving destructors
9 class DBConnection
10 {
11 public:
12 static DBConnection create();
13
14 void close();//关闭联机
15 };
16
17 class DBConn //这个class用来管理DBConnection
18 {
19 public:
20 void close()//供用户选择
21 {
22 db.close();
23 closed = true;
24 }
25 ~DBConn()
26 {
27 if (!closed)//如果客户不怎么做
28 {
29 try
30 {
31 db.close();
32 }
33 catch (...)//捕获所有异常
34 {
35 //记录 并结束程序 或吞下异常
36 }
37 }
38 }
39 private:
40 DBConnection db;
41 bool closed;
42 };
43
44 //provision_10 Have assignment operators return a reference to *this
45 //避免连锁赋值开销
46 #include<string>
47 #include<iostream>
48 class Str
49 {
50 public:
51 Str(const std::string& _s = "shuai") :i(6), s(_s)
52 {
53 std::cout << "default constructor " << std::endl;
54 }
55 Str(const Str& rhs) :i(rhs.i), s(rhs.s)
56 {
57 std::cout << "copy constructor" << std::endl;
58 }
59 Str& operator=(const Str& rhs)
60 {
61 i = rhs.i;
62 s = rhs.s;
63 std::cout << "copy & " << std::endl;
64 return *this;
65 }
66
67 /*Str operator=(const Str& rhs)
68 {
69 i = rhs.i;
70 s = rhs.s;
71 std::cout << "copy no & " << std::endl;
72 return *this;
73 }*/
74
75 ~Str()
76 {
77 std::cout << "destructor" << std::endl;
78 }
79 const auto& si() const { return i; }
80 const auto& ss() const { return s; }
81 private:
82 int i;
83 std::string s;
84 };
85 int main()
86 {
87 Str s1,s2("789"),s3("dui");
88 s1 = s2 = s3;
89 std::cout << "s2: "<<s2.ss() <<"s1: "<< s1.ss() << std::endl;
90 //operator=返回的no_reference 通过 copy constructor 给临时量
91 //但是临时量怎么给S2(临时量是s2产生的副本(猜测))的:或者返回给S2但是产生了一个临时量
92 //产生多余的copy constructor 和 destructor(临时量)
93 (s1 = s2) = s3;//这时s3 赋值给operator=(s1= s3) 所返回的临时量(返回类型时副本)
94 return 0;
95 }
96
97 //provision_11 Handle assignment to self in operator=
98 //问题:this,rhs 指向同一对象delete this会删除rhs所指向对象
99 class Bitmap {};
100 class Widget {
101 friend void swap(Widget&, Widget&);
102 Widget& operator=(const Widget& rhs);
103 Widget& operator=(Widget rhs);
104 private:
105 Bitmap* pb;
106 };
107 Widget&
108 Widget::operator=(const Widget& rhs)
109 {
110 delete pb;
111 pb = new Bitmap(*rhs.pb);//rhs.pb所指对象已经被delete
112 return *this;
113 }
114 //解决
115
116 //method one(identity test): 仍然存在潜在问题:Bitmao copy constructor exception
117 Widget&
118 Widget::operator=(const Widget& rhs)
119 {
120 if (this == &rhs) return *this;
121 delete pb;
122 pb = new Bitmap(*rhs.pb);//rhs.pb所指对象已经被delete
123 return *this;
124 }
125
126 //method two:high cost but opereator= 用到次数少
127 Widget&
128 Widget::operator=(const Widget& rhs)
129 {
130 auto temp = pb;
131 pb = new Bitmap(*rhs.pb);
132 delete temp;
133 return *this;
134 }
135
136 //method three(swap) swap:常用来优化代码 并且:如果成员含有子类会调用子类的swap
137 inline
138 void swap(Widget &lhs,Widget& rhs)
139 {
140 //当传递类类型的对象时,除了在常规的作用域查找外还会查找实参类所属的命名空间
141 using std::swap;
142 swap(lhs.pb, rhs.pb);//自定义的swap匹配优先级更高
143 }
144 Widget&
145 Widget::operator=(const Widget& rhs)
146 {
147 auto temp(rhs);
148 using std::swap; //
149 swap(*this, temp);
150 return *this;
151 }
152 Widget&
153 Widget::operator=(Widget rhs)//"copy 动作"从函数本体移至“函数参数构造阶段”
154 {
155 using std::swap;
156 swap(*this,rhs);
157 return *this;
158 }
159
160 /*
161 copy assignment and copy constructor 不要相互调用:构造:不存在对象, 赋值:对一个已经存在的对象
162 assignment call construct 对一个已经存在的对象进行构造(创建)
163 cosntructor call assignment 对一个还为构造(不存在)的对象进行赋值
164 */