2015-01-22 23 views
15

Trong ví dụ bên dưới, tại sao B::f() được gọi là mặc dù nó là riêng tư?Thành viên chức năng riêng được gọi ngoài lớp

Tôi biết thực tế này: Quyền truy cập được chọn tại điểm gọi sử dụng loại biểu thức được sử dụng để biểu thị đối tượng mà hàm thành viên được gọi.

#include <iostream> 

class A { 
public: 
    virtual void f() { std::cout << "virtual_function"; } 
}; 

class B : public A { 
private: 
    void f() { std::cout << "private_function"; } 
}; 

void C(A &g) { g.f(); } 

int main() { 
    B b; 
    C(b); 
} 
+2

Bởi vì nó là công khai trong A, có lẽ và do thực tế rằng A là một phụ huynh và bạn đang sử dụng nó từ một đối tượng A nó không bận tâm kiểm tra phạm vi trên đứa trẻ, nó chỉ bị ghi đè bởi thực tế là nó là công khai trong A. Chỉ là suy nghĩ của tôi. – tom

+3

Những gì bạn đã giải thích nó - kiểu tĩnh của 'g' trong' C' là 'A &', và 'f()' là một hàm thành viên công khai của 'A'. Đó là tất cả các điều khiển truy cập quan tâm. Thay đổi kiểu tham số 'C()' thành 'B &' và mã của bạn sẽ không biên dịch được. – Praetorian

Trả lời

23

Bởi vì tiêu chuẩn nói vậy:

[C++11: 11.5/1]: Các quy tắc truy cập (khoản 11) cho một hàm ảo được xác định bởi tuyên bố của mình và không bị ảnh hưởng bởi các quy tắc cho một chức năng mà sau này sẽ ghi đè nó. [Ví dụ:

class B { 
public: 
    virtual int f(); 
}; 
class D : public B { 
private: 
    int f(); 
}; 
void f() { 
    D d; 
    B* pb = &d; 
    D* pd = &d; 
    pb->f();  // OK: B::f() is public, 
       // D::f() is invoked 
    pd->f();  // error: D::f() is private 
} 

-end dụ]

Ví dụ cũng giống như bạn, lol.

4

Trong biên dịch thời gian C++ biên dịch xác minh khả năng tiếp cận các chức năng và phương pháp dựa trên kiểu của chúng. Trong hàm C biến g là loại A (được kiểm tra trong quá trình biên dịch mã), trong đó phương thức f được khai báo là công khai.

Hãy xem this link

6

private chức năng có thể ghi đè public chức năng ảo từ một lớp cơ sở. Hỗ trợ truy cập được, trong một thực tế, hoàn toàn bỏ qua khi xác định liệu một chức năng ghi đè khác, vì vậy ngay cả trong

// Redundant private for clarity: 
class A { private: virtual void foo(); }; 
class B : A { public: void foo(); }; 

B::foo ghi đè A::foo.

+2

Ví dụ này không phải là rất thú vị, cho rằng 'B' tuyên bố' foo' riêng giống như 'A' đã làm, _and_ nó kế thừa riêng. –

+0

@LightnessRacesinOrbit Đã điều chỉnh. – Columbo

+0

Nó vẫn có quyền thừa kế riêng. Điều đó có chủ ý không? Nếu vậy, hãy cân nhắc thêm 'riêng tư' vào đó? –

Các vấn đề liên quan