Từ Khóa Protected Trong C++
Vài năm cuối cùng khi tôi còn sử dụng C++ làm ngôn ngữ chính, tôi gần như không dùng đến từ khóa protected nữa. Tôi nhớ lại cuốn sách từng yêu thích nhất thời sinh viên: “Thiết kế và tiến hóa ngôn ngữ C++” (The Design and Evolution of C++), bản dịch tiếng Việt ghi nhận ở trang 235:
“… Mark Linton ghé thăm văn phòng tôi, đưa ra đề xuất đầy thuyết phục về việc bổ sung cấp độ kiểm soát thứ ba để hỗ trợ phong cách lập trình đang được phát triển trong thư viện Interviews tại Đại học Stanford. Chúng tôi cùng thảo luận và tạo ra từ khóa protected, biểu thị cho các thành viên của lớp…”
“… Mark chính là nhà thiết kế chính của Interviews. Lập luận của ông dựa trên kinh nghiệm thực tế và hàng loạt ví dụ từ mã nguồn cụ thể…”
“… Khoảng năm năm sau, Mark thậm chí cấm sử dụng các thành viên dữ liệu protected trong Interviews vì chúng trở thành nguồn gốc của hàng loạt lỗi chương trình…”
Tôi từng không thích protected, nhưng giờ đây khi thỉnh thoảng vẫn dùng C++, tôi đã bớt khắt khe hơn. Dù sao thì việc xây dựng thiết kế ổn định bằng C++ vốn đã khó khăn, vậy nên cứ để mọi thứ tự nhiên. Điều quan trọng là không nên dùng C++ cho các hệ thống then chốt.
Hôm nay, tôi gặp phải một vấn đề liên quan đến protected, khiến tôi hơi bực bội. Đây là một câu hỏi cơ bản, tưởng chừng đã quá quen thuộc từ lâu. Dù đã nhiều năm không đụng đến C++, tôi vẫn cảm thấy phần nào lúng túng với cú pháp.
Thuở nhỏ, tôi từng nghĩ đoạn mã sau là không hợp lệ:
|
|
Tôi lo lắng rằng phương thức foo::foobar sẽ không thể truy cập thành viên riêng tư a của đối tượng f.
Sau này tôi mới hiểu rằng tính “riêng tư” (private) trong C++ áp dụng cho cấp độ lớp (class), chứ không phải từng đối tượng cụ thể.
Tuy nhiên hôm nay, tôi lại gặp một tình huống khiến tôi giật mình:
|
|
Lần này, việc truy cập thành viên a của this là hợp lệ, nhưng truy cập a của con trỏ foo* f lại bị cấm.
Lý do là vì foo::a có mức truy cập protected đối với lớp foobar, nên hàm thành viên của foobar có thể truy cập a của chính nó, nhưng không được phép truy cập a thông qua con trỏ kiểu foo*.
Tôi suy nghĩ một hồi và tìm ra giải pháp như sau:
|
|
Cách này tuy có mùi vị khó chịu (bad smell), nhưng giờ tôi cũng không còn quá quan trọng chuyện đó nữa.