Effective C++ iterm5

条款五

--17/01/19

编译器为你生成了什么函数?

(1)如果的类什么构造函数都没有,那么编译器就帮助你自动生成一个默认构造函数,自动按照默认的方式初始化类的成员变量,所谓的按照默认的方式如调用base classes和non-static成员变量的构造函数。如果你的类拥有一个构造函数或以上的话,那么编译器将不帮你干任何事情。析构函数类似。

(2)接下来要重点讲的就是这个cppy构造函数和copy assignment运算符,函数的原型如下:

1 class C {
2 public:
3   C(const C& rhs) { ... }
4   C& operator = (const C& rhs) { ... }
5 };

当类的变量内含reference成员时,如果编译器还会帮我们生成一个copy构造函数吗?

写个程序测试一下:

 1 /*zhen hao*/
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4 
 5 class C {
 6 public:
 7   C() {}
 8   C(const string& _val) : _val(_val) {}
 9   string val() { return _val; }
10 private:
11   string _val;
12 };
13 
14 int main() {
15   C a("abc");
16   C b = a;
17   C c(a);
18   cout << a.val() << endl;
19   cout << b.val() << endl;
20   cout << c.val() << endl;
21   return 0;
22 }

由上面程序可见,没有显示声明cppy构造函数和copy assignment运算符,编译器自动帮我们生成了一个。

如将上述程序改成下面这个:

 1 /*zhen hao*/
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4 
 5 class C {
 6 public:
 7   C() {}
 8   C(const string& _val) : _val(_val) {}
 9   string val() { return _val; }
10 private:
11   string _val;
12 };
13 
14 int main() {
15   C a("abc");
16   C b = a;
17   C c(a);
18   cout << a.val() << endl;
19   cout << b.val() << endl;
20   cout << c.val() << endl;
21   return 0;
22 }

综上得出的结论就是:如果打算在一个“内含reference成员”的类支持赋值操作,必须自己定义一个copy assignment运算符,编译器不会帮你自动生成,对于内含const成员同理。还有一种情况:如果你的基类里面的copy assignment运算符是private的,那么编译器也不会帮你自动生成,因为他不能够帮你把基类的那部分也copy下来,面对这种无能为力的情况,编译器一般都会say no!

posted @ 2017-01-19 18:54  scoyer  阅读(179)  评论(0编辑  收藏  举报