2010-01-28 46 views
11

Tôi thực sự bối rối về thừa kế riêng và thừa kế được bảo vệ.Sự kế thừa bảo vệ có cho phép lớp dẫn xuất truy cập vào các thành viên riêng của lớp cơ sở của nó không?

1) trong kế thừa được bảo vệ, các thành viên công khai và được bảo vệ trở thành thành viên được bảo vệ trong lớp dẫn xuất. Trong kế thừa riêng, mọi thứ đều riêng tư. Tuy nhiên, lớp dẫn xuất không bao giờ có thể truy cập các thành viên riêng của lớp cơ sở, đúng không? Lớp dẫn xuất có thể truy cập các thành viên public và protected trong cả hai trường hợp. Có đúng không?

2) Tôi nhận thấy rằng các thành viên riêng của lớp cơ sở sẽ không bao giờ bị xúc động bởi lớp dẫn xuất. Vậy tại sao các thành viên tư nhân lại được thừa hưởng?

Trả lời

32

Bạn đúng ở điểm # 1. Chỉ định private, protected hoặc public khi kế thừa từ một lớp cơ sở không thay đổi bất kỳ thứ gì truy cập khôn ngoan trên lớp dẫn xuất. Các specifier truy cập này cho trình biên dịch biết cách xử lý các thành viên lớp cơ sở khi các cá thể của lớp dẫn xuất được sử dụng ở đâu đó, hoặc nếu lớp dẫn xuất xảy ra được sử dụng làm lớp cơ sở cho các lớp khác.

UPDATE: Sau đây có thể giúp để minh họa sự khác biệt:

class Base 
{ 
    private: int base_pri; 
    protected: int base_pro; 
    public: int base_pub; 
}; 

Đối với các lớp học có nguồn gốc từ cơ sở:

class With_Private_Base : private Base { void memberFn(); }; 
class With_Protected_Base : protected Base { void memberFn(); }; 
class With_Public_Base : public Base { void memberFn(); }; 

// this would be the same for all of the above 3 classes: 
void With_PXXX_Base::memberFn() 
{ 
    base_pri = 1; // error: `int Base::base_pri' is private 
    base_pro = 1; // OK 
    base_pub = 1; // OK 
} 

Đối với các lớp học có nguồn gốc từ 3 các lớp thừa kế:

class A : public With_Private_Base { void memberFn(); } 
void A::memberFn() 
{ 
    base_pri = 1; // error: `int Base::base_pri' is private 
    base_pro = 1; // error: `int Base::base_pro' is protected 
    base_pub = 1; // error: `int Base::base_pub' is inaccessible 
} 

class B : public With_Protected_Base { void memberFn(); } 
void B::memberFn() 
{ 
    base_pri = 1; // error: `int Base::base_pri' is private 
    base_pro = 1; // OK 
    base_pub = 1; // OK 
} 

class C : public With_Public_Base { void memberFn(); } 
void C::memberFn() 
{ 
    base_pri = 1; // error: `int Base::base_pri' is private 
    base_pro = 1; // OK 
    base_pub = 1; // OK 
} 

Truy cập bên ngoài vào ba lớp học có nguồn gốc đầu tiên:

void main() 
{ 
    With_Private_Base pri_base; 
    pri_base.base_pri = 1; // error: `int Base::base_pri' is private 
    pri_base.base_pro = 1; // error: `int Base::base_pro' is protected 
    pri_base.base_pub = 1; // error: `int Base::base_pub' is inaccessible 

    With_Protected_Base pro_base; 
    pro_base.base_pri = 1; // error: `int Base::base_pri' is private 
    pro_base.base_pro = 1; // error: `int Base::base_pro' is protected 
    pro_base.base_pub = 1; // error: `int Base::base_pub' is inaccessible 

    With_Public_Base pub_base; 
    pub_base.base_pri = 1; // error: `int Base::base_pri' is private 
    pub_base.base_pro = 1; // error: `int Base::base_pro' is protected 
    pub_base.base_pub = 1; // OK 
} 
+0

Thừa kế thừa kế và thừa kế công khai giống nhau? –

+0

@fahad: từ quan điểm của lớp dẫn xuất, có, chúng được. Từ một điểm truy cập bên ngoài của xem (khối cuối cùng của mã trong câu trả lời của tôi) họ là khá khác nhau. –

0

1) Bạn đã chính xác. Không có loại thừa kế nào cho phép truy cập vào các thành viên riêng tư (chỉ các khai báo friend cho phép điều đó)

2) Chúng được thừa kế theo nghĩa là một đối tượng kiểu Bắt nguồn, khi được lưu trữ trong bộ nhớ, bao gồm tất cả các thành viên dữ liệu Có nguồn gốc và cơ sở, bao gồm cả các thành viên riêng của Base. Các thành viên private không thể bỏ đi vì khi các phương thức Base chạy trên đối tượng đó, họ sẽ cần truy cập các thành viên riêng của Base.

Ngoài ra, tên của các thành viên riêng của Base về mặt kỹ thuật nằm trong các phương pháp của Derived, nhưng tất nhiên bạn sẽ gặp phải lỗi biên dịch nếu bạn cố truy cập chúng.

3

1a) Thừa kế được bảo vệ có nghĩa là "con" có thể truy cập mọi thứ có thể trong thừa kế công khai, nhưng những người khác sử dụng đối tượng đó chỉ có thể nhìn thấy giao diện công khai cho trẻ, bất kỳ thứ gì trong cha mẹ đều bị ẩn.

1b) Kết quả thừa kế riêng tư trong tất cả các chức năng công cộng của một lớp được kế thừa dưới dạng hàm riêng - nghĩa là chúng không thể được gọi từ con hoặc truy cập từ ứng dụng khách của đối tượng của bạn.

2) Các thành viên riêng được kế thừa vì các phương thức trong lớp cơ sở có thể cần chúng hoạt động.

1

1) trong thừa kế được bảo vệ, các thành viên cộng đồng và bảo vệ trở thành thành viên protected trong nguồn gốc lớp. Trong kế thừa riêng, mọi thứ đều riêng tư. Tuy nhiên, lớp học có nguồn gốc từ không bao giờ có thể truy cập thành viên riêng tư của lớp cơ sở, là đúng không?

Có.

Lớp dẫn xuất có thể truy cập công khai và được bảo vệ thành viên trong cả hai trường hợp. Có đúng không?

Có.

2) Tôi nhận thấy rằng các thành viên riêng tư của lớp cơ sở sẽ không bao giờ được xúc động bởi lớp dẫn xuất. Vậy tại sao là các thành viên riêng được thừa kế?

Vì chúng là một phần của lớp cơ sở và bạn cần lớp cơ sở là một phần của lớp học có nguồn gốc của bạn.Lưu ý, bạn vẫn có thể thao tác một số trạng thái (nếu có) được duy trì trong lớp cơ sở bằng cách sử dụng các hàm thành viên không được ghi đè public/protected thành viên.

2
  1. Có, điều này là chính xác. Các lớp có nguồn gốc có thể truy cập các thành viên được bảo vệ và công khai của lớp cơ sở của nó, và lớp dẫn xuất không thể truy cập các thành viên riêng của lớp cơ sở của nó.

  2. Các thành viên riêng được kế thừa vì lý do sau: Lớp cơ sở có thể định nghĩa một hàm được bảo vệ hoặc công khai để sửa đổi thành viên riêng của lớp cơ sở. Lớp dẫn xuất có thể gọi hàm này, và do đó cần biết về biến riêng tư mà nó truy cập.

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