Giả sử kiểm soát truy cập đến trước khi giải quyết quá tải. Về mặt hiệu quả, điều này có nghĩa là public/protected/private
khả năng hiển thị được kiểm soát hơn là khả năng truy cập.
Phần 2.10 của Thiết kế và Tiến hóa C ++ của Stroustrup có một đoạn về vấn đề này, nơi anh ấy thảo luận về ví dụ sau
int a; // global a
class X {
private:
int a; // member X::a
};
class XX : public X {
void f() { a = 1; } // which a?
};
Stroustrup đề cập rằng lợi ích của các quy tắc hiện tại (khả năng hiển thị trước khả năng truy cập) là (tạm thời) điều khiển private
bên trong class X
thành public
(ví dụ: cho mục đích gỡ lỗi) là không có sự thay đổi âm thầm trong ý nghĩa của chương trình trên (tức X::a
là được cố gắng được truy cập trong cả hai trường hợp, điều này gây ra lỗi truy cập trong ví dụ trên). Nếu public/protected/private
sẽ kiểm soát khả năng hiển thị, ý nghĩa của chương trình sẽ thay đổi (toàn cầu a
sẽ được gọi bằng private
, ngược lại X::a
).
Sau đó, anh ta nói rằng anh ta không nhớ liệu đó là do thiết kế rõ ràng hay do tác dụng phụ của công nghệ tiền xử lý được sử dụng để triển khai C với Classess tiền nhiệm cho Standard C ++.
Điều này liên quan đến ví dụ của bạn như thế nào? Về cơ bản vì Tiêu chuẩn thực hiện giải quyết quá tải tuân theo quy tắc chung rằng tra cứu tên được thực hiện trước kiểm soát truy cập.
10.2 Tra cứu tên thành viên [class.member.lookup]
1 Tra cứu tên thành viên xác định ý nghĩa của tên (biểu thức id) trong phạm vi lớp (3.3.7). Việc tra cứu tên có thể dẫn đến sự không rõ ràng, trong trường hợp đó, chương trình không được định hình tốt. Đối với biểu thức id, tra cứu tên bắt đầu trong phạm vi lớp của điều này; đối với id đủ điều kiện, tra cứu tên bắt đầu trong phạm vi của mã định danh tên lồng nhau. Việc tra cứu tên diễn ra trước khi kiểm soát truy cập (3.4, Khoản 11).
8 Nếu tên của một hàm quá tải được tìm thấy một cách rõ ràng, thì việc
giải quyết quá tải (13.3) cũng diễn ra trước khi kiểm soát truy cập . Sự mơ hồ thường có thể được giải quyết bằng cách đặt tên hợp lệ với tên lớp của nó.