Sự khác biệt giữa thừa kế riêng tư, công cộng và được bảo vệ


Câu trả lời:


1065

Để trả lời câu hỏi đó, trước tiên tôi muốn mô tả người truy cập của thành viên bằng từ ngữ của riêng tôi. Nếu bạn đã biết điều này, hãy bỏ qua tiêu đề "tiếp theo:".

Có ba accessors rằng tôi nhận thức: public, protectedprivate.

Để cho:

class Base {
    public:
        int publicMember;
    protected:
        int protectedMember;
    private:
        int privateMember;
};
  • Tất cả mọi thứ nhận thức Baseđược cũng nhận thức được Basecó chứa publicMember.
  • Chỉ có trẻ em (và con cái của họ) nhận thức được Basecó chứa protectedMember.
  • Không ai nhưng Basenhận thức được privateMember.

Bởi "nhận thức được", ý tôi là "thừa nhận sự tồn tại của, và do đó có thể truy cập".

kế tiếp:

Điều tương tự cũng xảy ra với thừa kế công cộng, tư nhân và được bảo vệ. Hãy xem xét một lớp Basevà một lớp Childkế thừa từ Base.

  • Nếu thừa kế là public, tất cả mọi thứ nhận thức được BaseChildcũng nhận thức được rằng Childthừa kế từ Base.
  • Nếu thừa kế là protected, chỉ Childvà con của nó, nhận thức được rằng chúng được thừa kế từ Base.
  • Nếu thừa kế là private, không ai khác ngoài Childnhận thức về thừa kế.

183
Tôi muốn thêm một vài từ mà khả năng hiển thị trong C ++ dựa trên lớp thay vì trên đối tượng, điều đó có nghĩa là các đối tượng cùng lớp có thể truy cập vào các trường riêng của nhau mà không bị hạn chế.
Zhe Chen

48
Nếu bạn gặp khó khăn trong việc hiểu điều này, hãy đọc câu trả lời của Kirill V. Lyadvinsky, sau đó quay lại và đọc nó.
Vivandiere

6
Đây chỉ là một trường hợp khác minh họa cách, phần lớn, kế thừa từ SomeBaseđó giống như một cách mã hóa cứng để soạn - trong một thành viên ẩn danh thuộc loại SomeBase. Điều này, giống như bất kỳ thành viên nào khác, có một công cụ xác định truy cập, thực hiện kiểm soát tương tự đối với truy cập bên ngoài.
gạch dưới

1
@ZheChen nếu tôi có đối tượng Tom và Jerry của lớp Người có tuổi trường riêng thì bạn truy cập (và sửa đổi như thế nào?) Tuổi của Jerry sử dụng Tom?
gen

2
Bạn có thể minh họa những gì bạn có nghĩa là "nhận thức về" thừa kế ""? Tôi có thể hiểu "tôi có thể truy cập cái này
neilxdims

1458
class A 
{
public:
    int x;
protected:
    int y;
private:
    int z;
};

class B : public A
{
    // x is public
    // y is protected
    // z is not accessible from B
};

class C : protected A
{
    // x is protected
    // y is protected
    // z is not accessible from C
};

class D : private A    // 'private' is default for classes
{
    // x is private
    // y is private
    // z is not accessible from D
};

LƯU Ý QUAN TRỌNG: Các lớp B, C và D đều chứa các biến x, y và z. Nó chỉ là câu hỏi truy cập.

Về việc sử dụng quyền thừa kế được bảo vệ và riêng tư, bạn có thể đọc ở đây .


35
Những gì Anzurio viết chỉ nhấp vào kết hợp với câu trả lời của bạn ngay bên dưới. Trả lời 1.
Idillotexist Idonotexist

2
Sự hiểu biết của tôi về cách thức hoạt động của nó là SO FAR OFF! Cảm ơn bạn rất nhiều vì đã làm rõ.
tjwrona1992

tôi phải mất một thời gian để hiểu điều này. Nhưng bây giờ thì rõ rồi. Cảm ơn!
Chân Kim

115

Hạn chế khả năng hiển thị của thừa kế sẽ làm cho mã không thể thấy rằng một số lớp kế thừa một lớp khác: Chuyển đổi ngầm định từ dẫn xuất sang cơ sở sẽ không hoạt động và static_casttừ cơ sở sang dẫn xuất sẽ không hoạt động.

Chỉ thành viên / bạn bè của một lớp có thể thấy thừa kế riêng tư và chỉ thành viên / bạn bè và các lớp dẫn xuất mới có thể thấy thừa kế được bảo vệ.

thừa kế công cộng

  1. IS-A thừa kế. Một nút là một cửa sổ, và bất cứ nơi nào cần một cửa sổ, một nút cũng có thể được thông qua.

    class button : public window { };

thừa kế được bảo vệ

  1. Được bảo vệ thực hiện theo các điều khoản. Hiếm khi hữu ích. Được sử dụng boost::compressed_pairđể lấy từ các lớp trống và lưu bộ nhớ bằng cách sử dụng tối ưu hóa lớp cơ sở trống (ví dụ bên dưới không sử dụng khuôn mẫu để tiếp tục duy trì điểm chính):

    struct empty_pair_impl : protected empty_class_1 
    { non_empty_class_2 second; };
    
    struct pair : private empty_pair_impl {
      non_empty_class_2 &second() {
        return this->second;
      }
    
      empty_class_1 &first() {
        return *this; // notice we return *this!
      }
    };

thừa kế tư nhân

  1. Thực hiện trong điều khoản của. Việc sử dụng lớp cơ sở chỉ để thực hiện lớp dẫn xuất. Hữu ích với các đặc điểm và nếu kích thước có vấn đề (các đặc điểm trống chỉ chứa các hàm sẽ sử dụng tối ưu hóa lớp cơ sở trống). Thường thì ngăn chặn là giải pháp tốt hơn. Kích thước cho chuỗi là rất quan trọng, vì vậy đây là cách sử dụng thường thấy ở đây

    template<typename StorageModel>
    struct string : private StorageModel {
    public:
      void realloc() {
        // uses inherited function
        StorageModel::realloc();
      }
    };

thành viên công cộng

  1. Tổng hợp

    class pair {
    public:
      First first;
      Second second;
    };
  2. Phụ kiện

    class window {
    public:
        int getWidth() const;
    };

thành viên được bảo vệ

  1. Cung cấp quyền truy cập nâng cao cho các lớp dẫn xuất

    class stack {
    protected:
      vector<element> c;
    };
    
    class window {
    protected:
      void registerClass(window_descriptor w);
    };

thành viên tư nhân

  1. Giữ chi tiết thực hiện

    class window {
    private:
      int width;
    };

Lưu ý rằng phôi kiểu C có chủ ý cho phép truyền một lớp dẫn xuất sang lớp cơ sở được bảo vệ hoặc riêng tư theo cách được xác định và an toàn và cũng chuyển sang hướng khác. Điều này nên tránh bằng mọi giá, vì nó có thể khiến mã phụ thuộc vào chi tiết triển khai - nhưng nếu cần, bạn có thể sử dụng kỹ thuật này.


7
Tôi nghĩ Scott Myers (nhiều như tôi thích công cụ của anh ấy) có rất nhiều câu trả lời cho sự nhầm lẫn chung. Bây giờ tôi nghĩ rằng sự tương tự của anh ấy về IS-A và IS-IMPLMENTED-IN-TERMS-OF là đủ cho những gì đang diễn ra.
DangerMouse

65

Ba từ khóa này cũng được sử dụng trong một ngữ cảnh hoàn toàn khác để chỉ định mô hình kế thừa khả năng hiển thị .

Bảng này tập hợp tất cả các kết hợp có thể có của mô hình kế thừa và khai báo thành phần thể hiện quyền truy cập kết quả vào các thành phần khi lớp con được xác định hoàn toàn.

nhập mô tả hình ảnh ở đây

Bảng trên được diễn giải theo cách sau (hãy xem hàng đầu tiên):

nếu một thành phần được khai báocông khai và lớp của nó được kế thừacông khai thì kết quả truy cậpcông khai .

Một ví dụ:

 class Super {
    public:      int p;
    private:     int q;
    protected:   int r;
 };

 class Sub : private Super {};

 class Subsub : public Sub {};

Kết quả là truy cập cho các biến p, q, rtrong lớp Subsubnone .

Một vi dụ khac:

class Super {
    private:     int x;
    protected:   int y;
    public:      int z;
 };
class Sub : protected Super {};

Quyền truy cập kết quả cho các biến y, ztrong lớp Sub được bảo vệ và đối với biến xkhông có .

Một ví dụ chi tiết hơn:

class Super {
private:
    int storage;
public:
    void put(int val) { storage = val;  }
    int  get(void)    { return storage; }
};
int main(void) {
    Super object;

    object.put(100);
    object.put(object.get());
    cout << object.get() << endl;
    return 0;
}

Bây giờ hãy xác định một lớp con:

class Sub : Super { };

int main(void) {
    Sub object;

    object.put(100);
    object.put(object.get());
    cout << object.get() << endl;
    return 0;
}

Lớp được định nghĩa có tên Sub là lớp con của lớp có tên Superhoặc Sublớp đó được lấy từ Superlớp. Các Subgiới thiệu lớp không biến mới hay các chức năng mới. Điều đó có nghĩa là bất kỳ đối tượng nào của Sublớp đều thừa hưởng tất cả các đặc điểm sau khi Superlớp thực sự là một bản sao của Supercác đối tượng của lớp?

Không . Nó không.

Nếu chúng tôi biên dịch mã sau đây, chúng tôi sẽ không nhận được gì ngoài các lỗi biên dịch nói rằng putgetcác phương thức không thể truy cập được. Tại sao?

Khi chúng ta bỏ qua trình xác định khả năng hiển thị, trình biên dịch giả định rằng chúng ta sẽ áp dụng cái gọi là thừa kế riêng . Điều đó có nghĩa rằng tất cả các cộng đồng thành phần lớp cha biến thành tin truy cập, các thành phần lớp cha tư nhân sẽ không thể truy cập vào tất cả. Do đó, điều đó có nghĩa là bạn không được phép sử dụng cái sau trong lớp con.

Chúng tôi phải thông báo cho trình biên dịch rằng chúng tôi muốn duy trì chính sách truy cập được sử dụng trước đó.

class Sub : public Super { };

Đừng nhầm lẫn : điều đó không có nghĩa là các thành phần riêng tư của Super class (như biến lưu trữ) sẽ biến thành công khai theo cách hơi kỳ diệu. Các thành phần riêng tư sẽ vẫn riêng tư , công khai sẽ vẫn công khai .

Các đối tượng của Sublớp có thể làm "gần như" những điều tương tự như anh chị lớn của họ được tạo ra từ Superlớp. "Hầu như" bởi vì thực tế là một lớp con cũng có nghĩa là lớp bị mất quyền truy cập vào các thành phần riêng của siêu lớp . Chúng ta không thể viết một hàm thành viên của Sublớp để có thể thao tác trực tiếp với biến lưu trữ.

Đây là một hạn chế rất nghiêm trọng. Có bất kỳ công việc xung quanh?

.

Cấp độ truy cập thứ ba được gọi là bảo vệ . Từ khóa được bảo vệ có nghĩa là thành phần được đánh dấu với nó hoạt động như một công khai khi được sử dụng bởi bất kỳ lớp con nào và trông giống như một thành phần riêng tư với phần còn lại của thế giới . - Điều này chỉ đúng với các lớp được kế thừa công khai (như lớp Siêu trong ví dụ của chúng tôi) -

class Super {
protected:
    int storage;
public:
    void put(int val) { storage = val;  }
    int  get(void)    { return storage; }
};

class Sub : public Super {
public:
    void print(void) {cout << "storage = " << storage;}
};

int main(void) {
    Sub object;

    object.put(100);
    object.put(object.get() + 1);
    object.print();
    return 0;
}

Như bạn thấy trong mã ví dụ, chúng ta có một chức năng mới cho Sublớp và nó thực hiện một điều quan trọng: nó truy cập biến lưu trữ từ lớp Super .

Sẽ không thể nếu biến được khai báo là riêng tư. Trong phạm vi hàm chính, biến vẫn được ẩn đi vì vậy nếu bạn viết bất cứ thứ gì như:

object.storage = 0;

Trình biên dịch sẽ thông báo cho bạn rằng nó là một error: 'int Super::storage' is protected.

Cuối cùng, chương trình cuối cùng sẽ tạo ra đầu ra sau:

storage = 101

4
Đầu tiên phải kể đến việc thiếu một công cụ sửa đổi (như trong Class: SuperClass) mang lại sự riêng tư. Đây là một phần quan trọng mà những người khác đang bỏ lỡ, cùng với những lời giải thích kỹ lưỡng. +1
Nước

2
Làm quá mức IMO, nhưng tôi thích cái bàn lúc đầu.
cp.engr

63

Nó có liên quan đến cách các thành viên công khai của lớp cơ sở được tiếp xúc từ lớp dẫn xuất.

  • công khai -> các thành viên công khai của lớp cơ sở sẽ ở chế độ công khai (thường là mặc định)
  • được bảo vệ -> các thành viên công cộng của lớp cơ sở sẽ được bảo vệ
  • riêng tư -> thành viên công khai của lớp cơ sở sẽ ở chế độ riêng tư

Như litb chỉ ra, thừa kế công khai là thừa kế truyền thống mà bạn sẽ thấy trong hầu hết các ngôn ngữ lập trình. Đó là mô hình mối quan hệ "IS-A". Kế thừa tư nhân, một cái gì đó đặc biệt của AFAIK đối với C ++, là mối quan hệ "THỰC HIỆN TRONG ĐIỀU KHOẢN". Đó là bạn muốn sử dụng giao diện chung trong lớp dẫn xuất, nhưng không muốn người dùng của lớp dẫn xuất có quyền truy cập vào giao diện đó. Nhiều ý kiến ​​cho rằng trong trường hợp này bạn nên tổng hợp lớp cơ sở, thay vì có lớp cơ sở làm cơ sở riêng, hãy tạo thành viên có nguồn gốc để sử dụng lại chức năng của lớp cơ sở.


13
Tốt hơn nên nói "công khai: mọi người sẽ được thừa kế". được bảo vệ: sự kế thừa sẽ chỉ được nhìn thấy bởi các lớp và bạn bè có nguồn gốc "," riêng tư: sự kế thừa sẽ chỉ được nhìn thấy bởi chính lớp và bạn bè ". Điều này khác với từ ngữ của bạn, vì không chỉ các thành viên có thể vô hình, mà còn mối quan hệ IS-A có thể là vô hình.
Johannes Schaub - litb

4
Một lần tôi đã sử dụng quyền thừa kế riêng là thực hiện đúng như những gì Doug T mô tả, tức là "bạn muốn sử dụng giao diện chung trong lớp dẫn xuất, nhưng không muốn người dùng của lớp dẫn xuất có quyền truy cập vào giao diện đó". Về cơ bản, tôi đã sử dụng nó để loại bỏ giao diện cũ và hiển thị một giao diện khác thông qua lớp dẫn xuất.
Giàu

36
Member in base class : Private   Protected   Public   

Kiểu kế thừa :              Đối tượng được kế thừa như :

Private            :   Inaccessible   Private     Private   
Protected          :   Inaccessible   Protected   Protected  
Public             :   Inaccessible   Protected   Public

23
Điều này gây hiểu lầm. Các thành viên riêng của một lớp cơ sở cư xử hoàn toàn khác với các thành viên của lớp tư nhân thông thường - họ hoàn toàn không thể truy cập được từ lớp dẫn xuất. Tôi nghĩ rằng cột ba "Riêng tư" của bạn phải là một cột "Không thể truy cập". Xem câu trả lời của Kirill V. Lyadvinsky cho câu hỏi này.
Sam Kauffman

27

1) Kế thừa công cộng :

a. Các thành viên riêng của lớp Base không thể truy cập được trong lớp Derogen.

b. Các thành viên được bảo vệ của lớp Base vẫn được bảo vệ trong lớp Derogen.

c. Các thành viên công khai của lớp Base vẫn công khai trong lớp Derogen.

Vì vậy, các lớp khác có thể sử dụng các thành viên công khai của lớp Cơ sở thông qua đối tượng lớp Derogen.

2) Bảo vệ quyền thừa kế :

a. Các thành viên riêng của lớp Base không thể truy cập được trong lớp Derogen.

b. Các thành viên được bảo vệ của lớp Base vẫn được bảo vệ trong lớp Derogen.

c. Các thành viên công khai của lớp Base cũng trở thành thành viên được bảo vệ của lớp Derogen.

Vì vậy, các lớp khác không thể sử dụng các thành viên công khai của lớp Cơ sở thông qua đối tượng lớp Derogen; nhưng chúng có sẵn cho lớp con của Derogen.

3) Kế thừa tư nhân :

a. Các thành viên riêng của lớp Base không thể truy cập được trong lớp Derogen.

b. Các thành viên được bảo vệ và công khai của lớp Cơ sở trở thành thành viên riêng của lớp Deriving.

Vì vậy, không có thành viên nào của lớp Base có thể được truy cập bởi các lớp khác thông qua đối tượng lớp Derogen vì chúng là riêng tư trong lớp Derogen. Vì vậy, ngay cả lớp con của lớp Derive cũng không thể truy cập chúng.


20

Kế thừa công khai mô hình mối quan hệ IS-A. Với

class B {};
class D : public B {};

mỗi D là một B .

Kế thừa tư nhân mô hình mối quan hệ IS-THỰC HIỆN-SỬ DỤNG (hoặc bất cứ điều gì được gọi là). Với

class B {};
class D : private B {};

một Dkhông một B, nhưng mỗi Dsử dụng của nó Btrong việc thực hiện của nó. Kế thừa tư nhân luôn có thể được loại bỏ bằng cách sử dụng ngăn chặn thay thế:

class B {};
class D {
  private: 
    B b_;
};

Điều này Dcũng có thể được thực hiện bằng cách sử dụng B, trong trường hợp này bằng cách sử dụng nó b_. Ngăn chặn là một khớp nối ít chặt chẽ hơn giữa các loại so với thừa kế, vì vậy nói chung nó nên được ưu tiên. Đôi khi sử dụng ngăn chặn thay vì thừa kế riêng tư không thuận tiện như thừa kế riêng tư. Thường thì đó là một cái cớ khập khiễng vì lười biếng.

Tôi không nghĩ có ai biết protectedmô hình thừa kế. Ít nhất tôi chưa thấy lời giải thích thuyết phục nào.


Một số người nói như một mối quan hệ. Giống như sử dụng ghế như một cái búa. Ghế ở đây: búa được bảo vệ
user4951

khi sử dụng ngăn chặn thay vì thừa kế tư nhân không thuận tiện như thừa kế tư nhân? Bạn sẽ giải thích nó bằng một ví dụ?
Kẻ hủy diệt

@Pravasi: Nếu Dxuất phát từ tư nhân D, nó có thể ghi đè các chức năng ảo của B. (Nếu, ví dụ, Blà một giao diện quan sát, sau đó Dcó thể thực hiện nó và vượt qua thischức năng đòi hỏi auch một giao diện, mà không cần tất cả mọi người có thể sử dụng Dnhư một người quan sát.) Ngoài ra, Dcó chọn lọc có thể làm cho các thành viên của Bsẵn trong giao diện của nó bằng cách thực hiện using B::member. Cả hai đều bất tiện về mặt cú pháp để thực hiện khi Blà thành viên.
sbi

@sbi: cũ nhưng ... ngăn chặn là không có trong trường hợp CRTP và / hoặc ảo (như bạn mô tả chính xác trong nhận xét - nhưng điều đó có nghĩa là nó không thể được mô hình hóa như ngăn chặn nếu B có phương pháp trừu tượng và bạn 'Không được phép chạm vào nó). protectedthừa kế Tôi thấy hữu ích với một virtuallớp cơ sở và protectedctor:struct CommonStuff { CommonStuff(Stuff*) {/* assert !=0 */ } }; struct HandlerMixin1 : protected virtual CommonStuff { protected: HandlerMixin1() : CommonStuff(nullptr) {} /*...*/ }; struct Handler : HandlerMixin1, ... { Handler(Stuff& stuff) : CommonStuff(&stuff) {} };
lorro

11

Nếu bạn thừa kế công khai từ một lớp khác, mọi người đều biết bạn đang thừa kế và bạn có thể được sử dụng đa hình bởi bất kỳ ai thông qua một con trỏ lớp cơ sở.

Nếu bạn kế thừa một cách bảo vệ, chỉ có các lớp con bạn mới có thể sử dụng bạn một cách đa hình.

Nếu bạn thừa kế riêng tư, bạn sẽ có thể thực thi các phương thức lớp cha.

Về cơ bản tượng trưng cho kiến ​​thức mà các lớp còn lại có về mối quan hệ của bạn với lớp cha mẹ của bạn


9

Các thành viên dữ liệu được bảo vệ có thể được truy cập bởi bất kỳ lớp nào kế thừa từ lớp của bạn. Thành viên dữ liệu riêng tư, tuy nhiên, không thể. Hãy nói rằng chúng ta có những điều sau đây:

class MyClass {
    private:
        int myPrivateMember;    // lol
    protected:
        int myProtectedMember;
};

Từ trong phần mở rộng của bạn đến lớp này, tham chiếu this.myPrivateMembersẽ không hoạt động. Tuy nhiên, this.myProtectedMembersẽ. Giá trị vẫn được gói gọn, vì vậy nếu chúng ta có một khởi tạo của lớp này được gọi myObj, thì nó myObj.myProtectedMembersẽ không hoạt động, do đó, nó có chức năng tương tự như một thành viên dữ liệu riêng tư.


8
Accessors    | Base Class | Derived Class | World
—————————————+————————————+———————————————+———————
public       |      y     |       y       |   y
—————————————+————————————+———————————————+———————
protected    |      y     |       y       |   n
—————————————+————————————+———————————————+———————
private      |            |               |    
  or         |      y     |       n       |   n
no accessor  |            |               |

y: accessible
n: not accessible

Dựa trên ví dụ này cho java ... Tôi nghĩ rằng một bảng nhỏ đáng giá ngàn lời nói :)


Java chỉ có quyền thừa kế công khai
Zelldon

Đây không phải là chủ đề để nói về java nhưng KHÔNG, bạn đã nhầm ... Hãy theo liên kết trong câu trả lời của tôi ở trên để biết chi tiết
Enissay

Bạn đã đề cập java vì vậy nó là chủ đề. Và ví dụ của bạn xử lý các specifier sử dụng trong jaca. Câu hỏi là về các công cụ xác định tính kế thừa không tồn tại trong Java đã tạo ra sự khác biệt. Nếu một trường trong siêu lớp là công khai và thừa kế là riêng tư thì trường đó chỉ có thể truy cập được trong lớp con. Bên ngoài không có dấu hiệu nếu lớp con mở rộng siêu lớp. Nhưng bảng của bạn chỉ giải thích các chỉ định cho trường và phương thức.
Zelldon

7

Tóm lược:

  • Riêng tư: không ai có thể nhìn thấy ngoại trừ trong lớp
  • Được bảo vệ: Các lớp riêng + dẫn xuất có thể thấy nó
  • Công cộng: thế giới có thể thấy nó

Khi kế thừa, bạn có thể (trong một số ngôn ngữ) thay đổi loại bảo vệ của thành viên dữ liệu theo hướng nhất định, ví dụ: từ được bảo vệ sang công khai.


6

Riêng tư:

Các thành viên riêng của một lớp cơ sở chỉ có thể được truy cập bởi các thành viên của lớp cơ sở đó.

Công cộng:

Các thành viên công khai của một lớp cơ sở có thể được truy cập bởi các thành viên của lớp cơ sở đó, các thành viên của lớp dẫn xuất của nó cũng như các thành viên nằm ngoài lớp cơ sở và lớp dẫn xuất.

Được bảo vệ:

Các thành viên được bảo vệ của một lớp cơ sở có thể được truy cập bởi các thành viên của lớp cơ sở cũng như các thành viên của lớp dẫn xuất của nó.


Nói ngắn gọn:

tư nhân : cơ sở

bảo vệ : cơ sở + dẫn xuất

công khai : cơ sở + dẫn xuất + bất kỳ thành viên nào khác


5

Tôi tìm thấy một câu trả lời dễ dàng và vì vậy tôi cũng nghĩ đến việc đăng nó để tham khảo trong tương lai.

Nó từ các liên kết http://www.learncpp.com/cpp-tutorial/115-inherribution-and-access-specifier/

class Base
{
public:
    int m_nPublic; // can be accessed by anybody
private:
    int m_nPrivate; // can only be accessed by Base member functions (but not derived classes)
protected:
    int m_nProtected; // can be accessed by Base member functions, or derived classes.
};

class Derived: public Base
{
public:
    Derived()
    {
        // Derived's access to Base members is not influenced by the type of inheritance used,
        // so the following is always true:

        m_nPublic = 1; // allowed: can access public base members from derived class
        m_nPrivate = 2; // not allowed: can not access private base members from derived class
        m_nProtected = 3; // allowed: can access protected base members from derived class
    }
};

int main()
{
    Base cBase;
    cBase.m_nPublic = 1; // allowed: can access public members from outside class
    cBase.m_nPrivate = 2; // not allowed: can not access private members from outside class
    cBase.m_nProtected = 3; // not allowed: can not access protected members from outside class
}

3

Về cơ bản, nó là sự bảo vệ truy cập của công chúng và các thành viên được bảo vệ của lớp cơ sở trong lớp dẫn xuất. Với sự kế thừa công khai, lớp dẫn xuất có thể thấy các thành viên công khai và được bảo vệ của cơ sở. Với thừa kế tư nhân, nó không thể. Với sự bảo vệ, lớp dẫn xuất và bất kỳ lớp nào có nguồn gốc từ đó có thể nhìn thấy chúng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.