Разница между частным, публичным и защищенным наследованием

В чем разница между наследованием public, private и protected в C++? Все вопросы, которые я нашел на SO, касаются конкретных случаев.

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
};

Важное примечание: классы B, C и D содержат переменных x, y и Z. Это просто вопрос доступа.

Об использовании protected и Private наследование можно прочитать здесь.

Комментарии (3)
Решение

Чтобы ответить на этот вопрос, я бы хотел сначала описать своими словами аксессоры member'ов. Если вы уже знаете это, переходите к заголовку "далее:".

Есть три аксессора, о которых я знаю: public, protected и private.

Пусть:

class Base {
    public:
        int publicMember;
    protected:
        int protectedMember;
    private:
        int privateMember;
};
  • Все, что знает о Base, также знает, что Base содержит publicMember.
  • Только дети (и их дети) знают, что Base содержит protectedMember.
  • Никто, кроме Base, не знает о privateMember.

Под "известно" я подразумеваю "признавать существование и, следовательно, иметь доступ".

следующий:

То же самое происходит с наследованием public, private и protected. Рассмотрим класс Base и класс Child, который наследуется от Base.

  • Если наследование является public, то все, что знает о Base и Child, также знает, что Child наследует от Base.
  • Если наследование является protected, только Child и его дети знают, что они наследуют от Base.
  • Если наследование является private, никто, кроме Child, не знает о наследовании.
Комментарии (12)

Ограничения видимости наследование будет сделать код не в состоянии видеть, что некоторый класс наследует другой класс: неявное преобразование от производного к базовому выиграл't работа, и метод static_cast` от базового к производному выиграл'т работу.

Только члены и друзья класса могут увидеть частные наследования, и только члены/друзья и производные классы могут увидеть защищенного наследования.

общие наследования

  1. Это-наследство. Кнопка-это окно, и везде, где нужны окна, кнопка может быть тоже прошел.

кнопка класса : Public окно { };

охраняемых наследования

  1. Защищен осуществлены в сроки-от. Редко бывает полезно. Используется в толчок::compressed_pair`, проистекают из пустых классов и экономить память, используя пустой базы оптимизации класса (пример ниже Не'т использовать шаблон, чтобы оставаться в точке):

структура empty_pair_impl : защищена empty_class_1 { non_empty_class_2 второй; };

пара структуру : частная empty_pair_impl { non_empty_class_2 &ампер;второй() { вернуть это->второй; }

&ампер empty_class_1;первый() { вернуть this; // обратите внимание, мы возвращаемся это! } };

частный наследования

  1. Осуществлены в сроки-от. Использование базового класса только для реализации производного класса. Полезно с такими же характеристиками и если размер имеет значение (пусто черты характера, которые содержат только функции будем использовать пустой базы оптимизации класса). Часто сдерживание хотя лучшее решение,. Размер для строк имеет решающее значение, поэтому он'ы часто видел использование здесь

шаблон<StorageModel имя_типа> строки структуры : частная StorageModel { общественные: пустота realloc() { // использует унаследованные функции StorageModel::realloc(); } };


общие член

  1. Совокупный

пара класса { общественные: Первый; Второй второй; };

  1. Аксессоры

окна класса { общественные: тип int getWidth() константный; };

охраняемых член

  1. Обеспечение доступа для производных классов

класса Stack { защищено: вектор<элемент> с; };

окна класса { защищено: пустота непредвиденное registerclass(window_descriptor Вт); };

частный член

  1. Сохранить детали реализации

окна класса { частная: инт ширина; };


Отметим, что c-стиля бросает намеренно позволяет литья производного класса к protected или Private базового класса в определенном и безопасном образе и тоже брошены в другом направлении. Этого следует избегать любой ценой, потому что он может сделать зависимый код на детали реализации, но, при необходимости, вы можете воспользоваться этой техникой.

Комментарии (1)

Это связано с тем, как открытые члены базового класса открываются из производного класса.

  • public -> открытые члены базового класса'будут открытыми (обычно по умолчанию)
  • protected -> публичные члены базового класса' будут защищены
  • private -> публичные члены базового класса'будут приватными

Как отмечает litb, публичное наследование - это традиционное наследование, которое встречается в большинстве языков программирования. То есть оно моделирует отношения "IS-A". Приватное наследование, что AFAIK свойственно C++, является "ВЗАИМОДЕЙСТВИЕМ В ТЕРМИНАХ" отношений. То есть вы хотите использовать публичный интерфейс в производном классе, но не хотите, чтобы пользователь производного класса имел доступ к этому интерфейсу. Многие утверждают, что в этом случае вы должны агрегировать базовый класс, то есть вместо того, чтобы иметь базовый класс как приватную базу, сделать его членом производного класса, чтобы повторно использовать функциональность базового класса.

Комментарии (2)

в Эти три ключевых слова используются в совершенно ином контексте, чтобы указать модель наследования видимости.

В этой таблице собраны все возможные комбинации компонент декларации и модель наследования, представив в результате чего доступ к компонентам для подкласса полностью определены.

![введите сюда описание изображения][1]

Приведенной выше таблице, интерпретируется следующим образом (взгляните на первую строку):

если компонент заявил А общие и класс наследство а общие в результате доступ составляет общие.

Пример:

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

 class Sub : private Super {};

 class Subsub : public Sub {};

В результате доступ к переменным п, п, р в класс суб составляет нет.

другой пример:

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

В результате доступ к переменным г, Z в класс суб составляет охраняемых и переменная " X " является нет.

более подробный пример:


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 
Комментарии (2)
Member in base class : Private   Protected   Public   

Наследование тип :              объект наследуется как:

Private            :   Inaccessible   Private     Private   
Protected          :   Inaccessible   Protected   Protected  
Public             :   Inaccessible   Protected   Public
Комментарии (1)

1) Открытое Наследование:

а. Частные члены базового класса доступны в производном классе.

б. Защищенные члены базового класса остаются защищенными в производном классе.

С. Открытые члены базового класса остаются открытыми и в производном классе.

Так, другие классы могут использовать открытые члены базового класса через производный объект класса.

2) Защищенное Наследование:

а. Частные члены базового класса доступны в производном классе.

б. Защищенные члены базового класса остаются защищенными в производном классе.

С. Открытые члены базового класса становятся слишком защищенными членами производного класса.

Так, другие классы могут'т использовать открытые члены базового класса через производный объект класса, но они доступны для подкласса производных.

3) Частная Наследство:

а. Частные члены базового класса доступны в производном классе.

б. Защищены & открытые члены базового класса становятся закрытыми членами производного класса.

Таким образом, ни один из членов базового класса могут быть доступны другим классам через объект производного класса, так как они являются закрытыми в производном классе. Таким образом, даже подкласса производных класс может'т получить к ним доступ.

Комментарии (0)

Модели общественного наследования это-отношения. С

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

каждый Д _ это ох Б.

Индивидуальные модели наследования есть-реализовано-через отношения (или что там, что'называется). С

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

А Д - это не на B, но все Д использует Б в ее реализации. Частная наследования, всегда могут быть устранены при использовании содержания:

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

Это Д, тоже можно реализовать с помощью "Б", в этом случае, используя его что. Сдерживание является менее жесткой связи между типами наследования, так что в целом он следует отдавать предпочтение. Иногда с помощью сдерживания, а не приватное наследование не так удобно, как частное наследство. Часто, что'ы отмазка для лени.

Я не'т думаю, что кто-то знает, что "защищенных" моделей наследования. По крайней мере, я не'т видели никакого убедительного объяснения пока.

Комментарии (4)

Если вы публично наследовать от другого класса, все знают, что вы унаследовали и может использоваться полиморфно кем-либо через базовый указатель класса.

Если вы наследуете protectedly сможете использовать вы полиморфно только вашим детям уроки.

Если вы наследуют в частном порядке, только сам сможешь исполнить методов родительского класса.

Что по сути символизирует знания остальных классов о ваших отношениях с вашими родителями класса

Комментарии (0)

Защищенные данные-члены могут быть доступны любые классы, которые наследуют от класса. Члены личные данные, однако, не может. Позвольте'ы сказать, что мы имеем следующее:

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

Из вашего дополнения к данному классу, ссылаясь на это.myPrivateMember выиграл't работа. Тем не менее, это.myProtectedMember будет. Значение по-прежнему герметичны, поэтому если у нас есть экземпляр этого класса под названием myObj, затем `myObj.myProtectedMember выиграл'т работу, так он похож на закрытый элемент данных.

Комментарии (0)
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

Основываясь на этот пример для Java... я думаю, что столик стоит тысячи слов :)

Комментарии (3)

Резюме:

  • Частная: никто не может видеть его, кроме В класса
  • Защищенный: частная + производные классы могут это увидеть
  • Общественные: мир может увидеть

При наследовании, вы можете (в некоторых языках) изменить тип защиты элемента данных в определенном направлении, например, из protected в public.

Комментарии (0)

Частная:

Частные члены базового класса могут быть доступны только члены базового класса .

Общественные:

Открытые члены базового класса можно обращаться к членам базового класса, членами производного класса, а также члены, которые не входят в базовый класс и производный класс.

Защищено:

Защищенные члены базового класса могут быть доступны членам базового класса, а также членов его производного класса.


Короче:

частный: основание

охраняемых: основание + производные

общие: база + производные + любой другой член

Комментарии (0)

Я нашла простой ответ и так думал о публикации для меня слишком в будущем.

Его от http://www.learncpp.com/cpp-tutorial/115-inheritance-and-access-specifiers ссылки/

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
}
Комментарии (0)

По сути, это защита доступа к публичным и защищенным членам базового класса в производном классе. При публичном наследовании производный класс может видеть публичные и защищенные члены базового. При частном наследовании - нет. При наследовании protected производный класс и все классы, производные от него, могут их видеть.

Комментарии (0)