C++ const¶
const
qualifiers 在 C 和 C++ 裡面都很常見,
但是觀念不清楚的話就不能好好利用,
以下做些觀念紀錄。
加上 const
關鍵字可以確保不該被改到的變數不被更動,
如果不小心寫錯更動到的話,
會在編譯時噴出錯誤。
- 該加 const 的儘量加
- 愈早加愈好
const in declaration¶
由右至左解釋變數宣告:
const X p // p is an X that is const
X const p // p is a const X
const X * p // p points to an X that is const
X const * p // p points to a const X
X * const p // p is a const pointer to an X
X const * const p // p is a const pointer to a const X
const X * const p // p is a const pointer to an X that is const
const X& p // p is a reference to an X that is const
X const& p // p is a reference to a const X
const in function parameters¶
void f1(const std::string& s); // Pass by reference-to-const
void f2(const std::string* sptr); // Pass by pointer-to-const
void f3(std::string s); // Pass by value
const member function¶
const member function 又稱為 inspectors,不會更動 object 裡的東西,也就是對於這個 object 沒有副作用:
class MyClass {
public:
void inspect() const; // This member promises NOT to change *this
void mutate(); // This member function might change *this
};
如果想要從 const member function 裡用 reference 的方式回傳 this
object 裡的 member 的話,
必須使用 reference-to-const 或是 by value:
class MyClass {
public:
// inspect member function will return ``this`` object's member
const std::string& inspect_pass_1() const; // Pass, the caller can't change the object
std::string& inspect_fail_1() const; // Compile-time error, the caller can change the object
const std::string inspect_pass_2() const; // Pass, the caller can't change the object
std::string inspect_pass_2() const; // Pass, the caller can't change the object
const std::string& inspect_pass_3(); // Pass
std::string& inspect_pass_4(); // Pass
const std::string inspect_pass_5(); // Pass
std::string inspect_pass_5(); // Pass
};
如果有 member 在 const member function 是會更動的, 但是仍然要把它視為 const member function, 則須把該 member 宣告為 mutable。
class MyClass {
public:
void inspect() const { ++count; }
mutable unsigned int count = 0;
};
const overloading¶
const-overloading 指的是有兩個名稱相同的 member function,差別只在 const, 所以 const 和 non-const 的 object 會呼叫到不同函數, 形成 overloading。
class MyClass {
public:
// Subscript operators often come in pairs
const MyClass& operator[] (unsigned index) const;
MyClass& operator[] (unsigned index);
};