Const Member Function คือ Member Function ที่ สัญญาว่าไม่จะแก้ไขข้อมูล (Data Members) ของ Object ที่เรียกใช้ มันช่วยให้ Code ปลอดภัยและชัดเจนกว่า
Syntax
class ClassName {
ReturnType functionName(Parameters) const; // const หลัง parameter list
};
โค้ดตัวอย่าง
#include <iostream>
using namespace std;
class Demo {
private:
int value;
public:
Demo(int x = 0) : value(x) {}
// Const Member Function - อ่านอย่างเดียว
int getValue() const {
// value = 10; // ❌ Error: Cannot modify member in const function
return value;
}
// Non-const Member Function - เขียนได้
void setValue(int v) {
value = v; // ✓ OK
}
// Overloading: const และ non-const version
int& getValueRef() { return value; } // Non-const: คืน Reference
const int& getValueRef() const { return value; } // Const: คืน Const Reference
};
int main() {
const Demo d1(28); // Const Object
Demo d2(8); // Non-const Object
// Const Object เรียกได้เฉพาะ Const Methods
cout << "d1 (const): " << d1.getValue() << endl; // ✓ OK
// d1.setValue(10); // ❌ Error: Cannot call non-const on const object
// Non-const Object เรียกได้ทั้งคู่
cout << "d2: " << d2.getValue() << endl;
d2.setValue(20);
cout << "d2 after set: " << d2.getValue() << endl;
// Overloading demo
d2.getValueRef() = 30; // ใช้ non-const version (ล่ามได้)
cout << "d2 via ref: " << d2.getValue() << endl;
const Demo& cref = d2;
// cref.getValueRef() = 40; // ❌ Error: const version คืน const ref
return 0;
}
ผลลัพธ์
d1 (const): 28
d2: 8
d2 after set: 20
d2 via ref: 30
กฎสำคัญของ Const Member Functions
| กฎ |
คำอธิบาย |
| Const Object | เรียกได้เฉพาะ Const Member Functions |
| Non-const Object | เรียกได้ทั้ง Const และ Non-const Functions |
| Overloading | สามารถมี Const และ Non-const Version เดียวกันได้ (Signature ต่างกันที่ const) |
| this Pointer | ใน Const Function: const ClassName* const this |
| Mutable | Member ที่ประกาศ mutable แก้ไขได้ใน Const Function |
Mutable Keyword (ข้อยกเว้น)
class Cache {
mutable int accessCount = 0; // นับการเข้าถึง - ไม่ส่งผลต่อ Logical State
int value;
public:
Cache(int v) : value(v) {}
int getValue() const {
accessCount++; // ✓ OK: mutable
return value;
}
int getAccessCount() const { return accessCount; }
};
int main() {
const Cache c(42);
cout << c.getValue() << endl; // 42
cout << c.getValue() << endl; // 42
cout << "Accessed: " << c.getAccessCount() << " times" << endl; // 2 times
}
Use Cases ของ Mutable
- Caching / Memoization
- Reference Counting (ใน Smart Pointer Implementation)
- Lock/Mutex สำหรับ Thread Safety (mutable mutex)
- Logging / Debug Counters
- Lazy Initialization
Const Correctness Best Practices
- ใส่ const ให้มากที่สุด - ทุก Function ที่ไม่แก้ไข State
- Parameters: ใช้
const Type& สำหรับ Pass by Reference
- Return Types: คืน
const Type& สำหรับ Getters (หลีกเลี่ยง Copy)
- Iterators: ใช้
const_iterator / cbegin() / cend()
- Standard Library: STL Containers มี Const Overloads ครบ
// ✓ Good Const Correctness
class Good {
vector<int> data;
public:
// Const Getter - คืน Const Reference
const vector<int>& getData() const { return data; }
// Non-const Getter - คืน Non-const Reference (ต้องการแก้ไข)
vector<int>& getData() { return data; }
// Const Method ใช้ Const Iterator
void print() const {
for (auto it = data.cbegin(); it != data.cend(); ++it)
cout << *it << " ";
}
};
// ✗ Bad
class Bad {
vector<int> data;
public:
vector<int> getData() { return data; } // ❌ Return by value (Copy) + Non-const
void print() { /* non-const */ } // ❌ ไม่มี const version
};
Const และ Pointers/References
| Declaration |
ความหมาย |
const int* p | Pointer to const int (ข้อมูล const) |
int* const p | Const pointer to int (Pointer const) |
const int* const p | Const pointer to const int (ทั้งคู่ const) |
const int& ref | Reference to const int |
สรุป
const หลัง Parameter List = Const Member Function
- Const Object ใช้ได้แค่ Const Methods
- Non-const Object ใช้ได้ทั้งคู่
- Overload ได้ด้วย Const Qualifier
mutable สำหรับข้อยกเว้น (Logical Constness)
- Const Correctness = Code ที่ปลอดภัย อ่านง่าย Maintain ง่าย