Jul 14, 2013

Câu chuyện về *const member method*


Câu chuyện về *const member function*


Một ngày vật lộn với cái paper. Chỉ còn chút xíu nữa thôi là thông xong. Tuy nhiên buổi chiều rảnh rỗi, mình lại nhớ đến vụ const member funciton mà mình muốn viết về nó chăm ba chút.

Nếu rảnh rỗi sinh nông nổi và không có chuyện gì để làm. Ta có thể mò đến trang về phương thức at của container vector. Rảnh rỗi nữa có thể xem luôn operator[] của container vector luôn.. Điều gì hay ho vậy? Ở đây có tới 2 hàm được overload (dịch là: chồng hàm, bên congdongc thì là quá tải hàm. Mình thì thích overload hơn ^_^ ).

Phương thức at và toán tử [] khác nhau ở điểm nào nhỉ? at có exception văng ra còn toán tử [] thì lại không.

Một chút về phần định nghĩa. Tụi MSDN có nói: const member function là một phương thức không làm thay đổi đối tượng khi được gọi. Nó CHỈ có thể thay đổi các giá trị static và gọi các const member function khác của object. Từ khóa const được dùng trong phần khai báo và phần định nghĩa.

Và như vậy, const object chỉ có thể gọi được các const member function. Tuy nhiên, const member funciton thì có thể được gọi từ non-const object và const object.

Hiểu tới đây thì vẫn chưa giải thích vì sao lại có 2 phương thức at và 2 toán tử []. Giờ là lúc xét ví dụ dưới đây:


1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/*
*Example about const member function
*/
#include <iostream>

using namespace std;

class Point
{
private:
 int x, y;
public:
 Point() {};
 ~Point() {};
 const int& X(void) const {return this->x;}; // (1)
 Point& X(const int& x) { this->x = x; return *this;} ; //(2)
};
class Line
{
private:
 Point e1, e2;
public:
 const Point& E1() const {return this->e1;} ; // (3)
 Point& E1() {return this->e1;}; // (4)
 Line() {};
 ~Line() {};

};
int main()
{
 Line l;
 l.E1().X(10);
 //l.E1().X(10);
 return 0;
}

Đoạn code trên "nhại" lại phương thức at 1 chút. Và ta đã rõ: những phương thức nào cần truy xuất để lấy các giá trị (getter) thì ta cài đặt là const member function, còn phương thức nào nhằm thay đổi nội tại giá trị (trong ví dụ là thay đổi hành độ của 1 đỉnh trong đoạn thẳng) thì ta dùng non-const member function

Nhiều lúc vì vội vàng, mình chỉ đơn giản tạo 1 const member function mà không tạo 1 bản non-const. Chính điều đó khiến đôi lúc gặp phải những lỗi rất khó chịu, và thường với các đồ án lớn, việc debug trở nên một cực hình. Khi viết 1 hàm, ta cần phải suy nghĩ kĩ: có bao giờ hàm này làm thay đổi giá trị, hay gián tiếp làm thay đổi giá trị của đối tượng không? Như ví dụ trên, bên trong hàm const không hề có 1 câu lệnh nào làm thay đổi đối tượng, ta chỉ thông qua qua nó để thay đổi giá trị con (giá trị hoành độ).