Частные и защищенные члены: C ++ - PullRequest
244 голосов
/ 22 октября 2008

Может ли кто-нибудь объяснить мне разницу между private и protected членами в классах?

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

Какая разница и какую мне использовать?

Ответы [ 17 ]

336 голосов
/ 22 октября 2008

Частные члены доступны только в пределах определяющего их класса.

Защищенные члены доступны в классе, который их определяет, и в классах, которые наследуются от этого класса.

Редактировать: оба также доступны друзьям их класса, а в случае защищенных участников - друзьям их производных классов.

Редактировать 2: Используйте все, что имеет смысл в контексте вашей проблемы. Вы должны стараться сделать членов закрытыми, когда вы можете уменьшить связывание и защитить реализацию базового класса, но если это невозможно, используйте защищенные члены. Проверьте C ++ FAQ для лучшего понимания проблемы. Этот вопрос о защищенных переменных также может помочь.

124 голосов
/ 22 октября 2008

Public члены класса A доступны для всех и каждого.

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

Закрытые члены класса A недоступны вне кода A или из кода любого класса, полученного из A.

Итак, в конце концов, выбор между защищенным или частным ответит на следующие вопросы: Какое доверие вы готовы оказать программисту производного класса?

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

58 голосов
/ 22 октября 2008

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

class Base {

private: 
  int MyPrivateInt;
protected: 
  int MyProtectedInt;
public:
  int MyPublicInt;
};

class Derived : Base
{
public:
  int foo1()  { return MyPrivateInt;} // Won't compile!
  int foo2()  { return MyProtectedInt;} // OK  
  int foo3()  { return MyPublicInt;} // OK
};‌‌

class Unrelated 
{
private:
  Base B;
public:
  int foo1()  { return B.MyPrivateInt;} // Won't compile!
  int foo2()  { return B.MyProtectedInt;} // Won't compile
  int foo3()  { return B.MyPublicInt;} // OK
};

С точки зрения «лучшей практики», это зависит. Если даже есть слабая вероятность того, что кто-то захочет получить новый класс из вашего существующего и ему нужен доступ к внутренним членам, сделайте их Защищенными, а не Приватными. Если они закрытые, ваш класс может стать трудным для наследования.

21 голосов
/ 22 октября 2008

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

8 голосов
/ 22 октября 2008

Все зависит от того, что вы хотите сделать, и от того, что вы хотите, чтобы производные классы могли видеть.

class A
{
private:
    int _privInt = 0;
    int privFunc(){return 0;}
    virtual int privVirtFunc(){return 0;}
protected:
    int _protInt = 0;
    int protFunc(){return 0;}
public:
    int _publInt = 0;
    int publFunc()
    {
         return privVirtFunc();
    }
};

class B : public A
{
private:
    virtual int privVirtFunc(){return 1;}
public:
    void func()
    {
        _privInt = 1; // wont work
        _protInt = 1; // will work
        _publInt = 1; // will work
        privFunc(); // wont work
        privVirtFunc(); // wont work
        protFunc(); // will work
        publFunc(); // will return 1 since it's overridden in this class
    }
}
5 голосов
/ 22 октября 2008

Атрибуты и методы, помеченные как protected, - в отличие от частных - все еще видны в подклассах.

Если вы не хотите использовать или предоставлять возможность переопределить метод в возможных подклассах, я бы сделал их private.

4 голосов
/ 22 октября 2008

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

Вы можете иметь частное, защищенное и открытое наследование в C ++, которое будет определять, к каким производным классам можно обращаться в иерархии наследования. Например, в C # есть только публичное наследование.

4 голосов
/ 22 октября 2008

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

Конечно, функции друзей выбрасывают это в окно, ну да ладно.

4 голосов
/ 22 октября 2008

Обязательно посмотрите на вопрос Переменные защищенного члена . Рекомендуется использовать private по умолчанию (как в C ++ class ses) для уменьшения связи. Защищенные переменные-члены чаще всего являются плохой идеей, например, функции защищенных членов можно использовать, например, шаблон шаблона.

3 голосов
/ 01 апреля 2017

личное = доступно только для корабля (базовый класс) (т.е. только мой родитель может войти в спальню моего родителя)

защищено = доступно для корабля (базовый класс) и ее дочерей (т.е. только мой родитель может войти в спальню моих родителей, но разрешил сыну / дочери войти в спальню родителей)

общедоступно = доступно для материнства (базовый класс), дочери и всех остальных (т.е. только мой родитель может войти в спальню моего родителя, но это домашняя вечеринка - mi casa su casa)

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