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 */
原文地址:https://www.cnblogs.com/Z-s-c11/p/14147971.html