2013-05-21 17 views
6

Tôi nghĩ rằng nó bởi vì các thành viên lớp cơ sở dữ liệu và phương pháp sẽ không thể truy cập được, nhưng tôi muốn một số rõ ràng hơn về điều này. Ngoài ra, đây có phải là lý do tại sao đa hình (sử dụng các chức năng ảo) có thể chỉ dưới sự thừa kế công khai?lý do tại sao một con trỏ cơ sở trỏ đến đối tượng có nguồn gốc chỉ dưới sự kế thừa công khai?

+0

có thể trùng lặp của [Thừa kế công khai và riêng tư trong C++] (http: // stackoverflow.com/questions/4619791/public-and-private-inheritance-in-c) –

Trả lời

12

Thực ra, một con trỏ tới cơ sở có thể trỏ đến một lớp dẫn xuất ngay cả khi cơ sở là riêng tư. Vấn đề là chuyển đổi như vậy là không thể từ bên ngoài lớp học. Tuy nhiên, vẫn có thể thực hiện chuyển đổi như vậy trong ngữ cảnh nơi cơ sở có thể truy cập được.

Ví dụ:

#include <iostream> 
using namespace std; 

struct Base 
{ 
    void foo() const { 
     cout << "Base::foo()\n"; 
    } 
}; 

struct Derived : private Base 
{ 
    const Base* get() const { 
     return this; // This is fine 
    } 
}; 

int main() 
{ 
    Derived d; 
    const Base *b = &d; // This is illegal 
    const Base *b = d.get(); //This is fine 
    b->foo(); 
} 

Live example

Live example with virtual call

+0

Và tất nhiên cũng vậy với các chức năng ảo. – syam

+0

@Angew, hiểu rồi! cảm ơn rất nhiều! nhưng tôi vẫn muốn hiểu rõ hơn về lý do tại sao thời gian chạy đa hình chỉ được phép theo thừa kế công khai. – g3nair

+0

@ g3nair Bạn có ý nghĩa gì với "đa hình thời gian chạy" chính xác? Bạn có nghĩa là chuyển đổi từ gốc sang cơ sở? Nếu vậy, lý do là thừa kế công khai đại diện cho ** IS-A **, trong khi thừa kế được bảo vệ/riêng thường được gọi là "được triển khai trong điều khoản". – Angew

1

Nếu tôi đúng, bạn đang yêu cầu về các yếu tố tầm nhìn bên trong một lớp. Như bạn đã nêu công khai/bảo vệ/riêng tư sẽ ảnh hưởng đến khả năng truy cập của các thành viên/chức năng thành viên/phương pháp của bạn. (xem Difference between private, public, and protected inheritance) Tuy nhiên đa hình không bị giới hạn đối với thừa kế công khai.

dụ:

class B 
{ 
    protected: 
     virtual void do_B() = 0; 
}; 

class A : protected B 
{ 
    virtual void do_B() {}; 
}; 
+0

liên kết rất hữu ích. cảm ơn bạn! – g3nair

1

Dưới đây là một ví dụ mà sẽ giúp bạn hiểu rõ hơn

class Base{ 
    public: 
    int foo; 
}; 
class Derived: private Base{ 
    public: 
    int bar; 
}; 

Bây giờ trong chương trình này cho phép xem những gì các đối tượng lớp dẫn xuất có thể làm. Đối tượng lớp dẫn xuất có thể

  • Truy cập thanh biến số nguyên một cách công khai.
  • Truy cập biến số nguyên foo riêng (chỉ trong lớp Bắt nguồn) vì quan hệ thừa kế là riêng tư.

Bây giờ, hãy xem điều gì sẽ xảy ra nếu con trỏ Cơ sở có thể thực hiện nếu nó được tạo để trỏ đến đối tượng đó. Đối với con trỏ của lớp cơ sở,

  • Con trỏ cơ sở không thể truy cập thanh biến vì chỉ trỏ đến phần cơ sở của đối tượng lớp dẫn xuất.
  • Và theo con trỏ lớp cơ sở, biến foo là công khai, Vì nó đã được định nghĩa trong lớp cơ sở là công khai.

Vì vậy, bây giờ bạn có thể thấy sự mơ hồ mà con trỏ cơ sở sẽ đối mặt nếu nó trỏ tới đối tượng của lớp được kế thừa dưới quan hệ riêng tư.

Sự mơ hồ: Theo đối tượng lớp dẫn xuất foo là riêng tư, nhưng con trỏ cơ sở coi nó là công khai.

Vì vậy, tinh thần thừa kế riêng tư hoặc được bảo vệ bị mất nếu những thứ như vậy được cho phép. Tôi hy vọng điều này sẽ làm rõ sự nghi ngờ của bạn.