1 //
2 // 2015-03-05 03/55
3 // 指针、返回值、成员函数 之 const
4 //
5
6 #include <iostream>
7 #include <string>
8
9 using namespace std;
10
11 // ------------------------------
12 // 1. 指针的const
13 // ------------------------------
14 const char *p1 = "Hello"; // p 指向的是常量
15 char* const p2 = "Hello"; // p 本身是常量
16 const char* const p3 = "Hello"; // p 本身是常量,指向的也是常量
17
18 // ------------------------------
19 // 2. 返回值的const
20 // ------------------------------
21 string foo()
22 {
23 return "Hello";
24 }
25
26 int main(int argc, char *argv[])
27 {
28 // 以下这是合法的,将 foo 的声明改为 const string foo()
29 // 则不再合法,将返回声明为const可以避免'=='误写为'='。
30 foo() = "abc";
31 return 0;
32 }
33
34 // ------------------------------
35 // 3. 成员函数的const
36 // ------------------------------
37 class bar
38 {
39 public:
40 void func()
41 { cout << "non-const func is called"; }
42
43 void func() const
44 { cout << "the const func is called"; }
45
46 // 成员函数 const 属性可以构成重载的,我们知道非静态成员函数都隐含 this 指针,
47 // 所有 const 与 non-const 成员函数可以理解为下面的声明:
48 // void func(bar *this); (1)
49 // void func(const bar *this); (2)
50 // 一个 non-const 对象,可以调用 (1) & (2),const 对象只能调用 (2)。
51 };
52
53 int main(int argc, char *argv[])
54 {
55 // this 是 bar* 类型,可以赋值给 const 没问题,
56 // 按照 non-const -- const 匹配调用,如果没有
57 // 定义 non-const 版本,那么可以调用 const 的。
58 bar b;
59 b.func();
60
61 // 只能调用 const 版本,this 是 const bar* 类型。
62 const bar cb;
63 cb.func();
64 }
65
66 // ----------------------------------------------
67 // 4. 成员函数因const重载而引起的代码冗余
68 // ----------------------------------------------
69 class TextBlock
70 {
71 public:
72 TextBlock() : text("Hello")
73 {}
74
75 // const 版本
76 const char& operator[](const size_t pos) const
77 {
78 cout << "the const operator[] is called" << endl;
79 return text[pos];
80 }
81
82 // non-const 版本可以调用 const 版本
83 char& operator[](const size_t pos)
84 {
85 cout << "non-const operator[] is called" << endl;
86 return const_cast<char&>(
87 static_cast<const TextBlock&>(*this)[pos]
88 );
89 }
90 private:
91 string text;
92 };
93
94 int main(int argc, char *argv[])
95 {
96 TextBlock tb;
97 tb[1] = 'J'; // OK call non-const
98
99 const TextBlock ctb;
100 cout << ctb[1] << endl;
101
102 // Error 返回类型是 const 的引用,不能赋值。
103 // 其实如果只是返回简单变量 char f(),也不能赋值。
104 ctb[1] = 'H';
105 }
106
107 // ----------------------------------------------
108 // 5. mutable 的使用
109 // ----------------------------------------------
110 class TextBlock
111 {
112 public:
113 TextBlock() : text("Hello"), lengthValid(false)
114 {}
115
116 size_t length() const // 这里size_t是简单类型,返回不用设置const即可。
117 {
118 if (!lengthValid)
119 {
120 textLength = strlen(text);
121 lengthValid = true;
122 }
123 return textLength;
124 }
125 private:
126 char *text;
127 mutable bool lengthValid;
128 mutable size_t textLength;
129 };