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!