11/*
223- * @Last Modified time: 2016-04-11 22:47:29
3+ * @Last Modified time: 2016-09-15 15:53:55
44 */
55
66#include < iostream>
@@ -10,7 +10,20 @@ class MyClass
1010{
1111private:
1212 int counter;
13+
1314public:
15+ MyClass (){
16+ counter = 100 ;
17+ }
18+
19+ /*
20+ 成员函数的 const 和 non-const 是重载版本, 各自的隐藏参数分别是 const *this 和 *this.
21+
22+ 1. non-const 对象调用 non-const 函数,如果没有对应的 non-const 函数,则调用 const 函数
23+ 因为 non-const *this 指针可以隐式转换为 const *this 指针, 反之则不能。
24+ 2. const 对象只能调用 const 成员函数
25+ 因为const 对象调用成员函数时,传递 const this 指针, non-const 函数只接受普通的this 指针
26+ */
1427 void Foo ()
1528 {
1629 counter++;
@@ -24,23 +37,84 @@ class MyClass
2437 std::cout << " Foo const" << std::endl;
2538 }
2639
40+ void Bar (){
41+ std::cout << " Bar const" << std::endl;
42+ }
43+
44+ // const 参数
45+ void add (const int another){
46+ counter += another;
47+ // another = 12; // Error!
48+ std::cout << counter << endl;
49+ }
50+
51+ // 返回值为 const 类型
52+ const int & get_c (){
53+ return counter;
54+ }
55+
56+ int & get (){
57+ return counter;
58+ }
2759};
2860
2961int main (){
3062
31- // 2. 对常量的引用
63+ // 对常量的引用不能用作修改它绑定的对象
3264 int num = 10 ;
3365 const int &ref = num;
3466 num += 100 ;
3567 // ref += 100; // 编译不通过
3668 // cannot assign to variable 'b' with const-qualified type 'const int &'
3769 cout << num << endl;
3870
39- // 6. 成员函数后面加 const
71+ // const 成员函数和 non-const成员函数
4072 MyClass c;
4173 const MyClass& const_c = c;
4274 c.Foo ();
4375 const_c.Foo ();
76+ c.Bar ();
77+ // const_c.Bar(); // Error, 'this' argument has type 'const MyClass', but function is not marked const.
78+
79+ c.get () = 1000 ;
80+ cout << c.get () << endl;
81+ // c.get_c() = 1000; // Error!
82+
83+ // const pointer and pointer to const
84+ int i=10 , j=20 ;
85+ const int *p_to_const = &i;
86+ // *p_to_const = 11; // Error.
87+ p_to_const = nullptr ; // OK.
88+ int *const const_p = &i;
89+ // const_p = nullptr; // Error.
90+ *const_p = 12 ; // OK.
91+ const int *const c_p_to_const = &i;
92+ // c_p_to_const = nullptr; // Error.
93+ // *c_p_to_const = 12; // OK.
94+
95+
96+ /* 顶层 const 和 底层 const
97+ * 在执行对象的拷贝动作时,常量是顶层const 时不受影响。
98+ * 另一方面,底层 const 的限制不能忽视,当执行拷贝操作时,拷入和拷出的对象必须具有相同的底层 const 资格,
99+ * 或者两个对象的数据类型必须能够转换。
100+ */
101+
102+ int tmp = 22 ;
103+ const int const_tmp = 88 ; // 顶层 const
104+ tmp = const_tmp; // OK, 常量是顶层const 时不受影响
105+ std::cout << tmp << endl;
106+ const int *p2 = &tmp; // 底层 const,允许改变 p2 的值
107+ int tt = 10 ;
108+ const int *const p3 = &tt; // 前一个为顶层const, 后一个为顶层const
109+ p2 = p3; // OK,
110+ std::cout << *p2 << std::endl;
111+
112+ // int *pp = p3; // Error. p3 包含底层 const 的定义, 而 pp 没有
113+ const int *ppp = p3; // OK.
114+ int *pInt = &tmp;
115+ ppp = pInt; // int * 能够转换为 const int *
44116
117+ // int &r = const_tmp; // 普通的 int& 不能绑定到 int 常量上
118+ const int &r2 = tmp; // const int& 可以绑定到一个普通 int 上
45119 return 0 ;
46120}
0 commit comments