2008-10-22 2 views
200

Может ли кто-нибудь просветить меня о различии между частными и защищенными членами в классах? Я понимаю из передовых практик, что переменные и функции, которые не называются вне класса, должны быть закрытыми - но, глядя на мой проект MFC, MFC, похоже, защищен.Частные и защищенные участники: C++

В чем разница, и что я должен использовать?

ответ

287

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

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

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

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

+7

Ссылки на C++ FAQ Lite перешел на https://isocpp.org/wiki/faq/basics-of-inheritance – avner 2015-08-14 05:50:51

5

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

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

+1

Производный класс может переопределять частные виртуальные функции своей базы – 2008-10-22 09:18:01

+0

Ах да, вы правы. Благодаря! – fhe 2008-10-22 10:52:30

4

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

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

4

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

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

44

Доступ к защищенным элементам осуществляется из производных классов. Частные не могут.

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

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

+3

Я прошу отличить: если есть небольшая вероятность, что подкласс _no_ ему понадобится, сделайте его закрытым. Если у вас нет _intend_, чтобы ваш класс был подклассом, используйте шаблон метода шаблона. – xtofl 2008-10-22 09:42:51

21

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

105

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

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

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

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

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

+0

Производный класс должен быть типом вашего класса, а защищенные данные базового класса являются частью данных производного класса. Предполагается, что автор производного класса корректно обрабатывает эти данные или это ошибка. Частные данные в базовом классе - это, однако, то, что автор производного класса не контролирует. – CashCow 2016-10-11 11:35:17

+0

@CashCow `защищенные данные базового класса являются частью данных производного класса. Действительно. Разве не лучше, чтобы писатель производного класса объявил, что данные в их классе вместо моего? ... :-) ... `Предполагается, что автор производного класса правильно обрабатывает эти данные или это ошибка. В шаблоне NVI цель состоит в том, чтобы сделать все частным, включая методы, ограничить ущерб, который создатель производного класса мог бы сделать для иерархии. Защищенные методы уже являются потенциальной проблемой. Я не уверен, что усугублять это, используя защищенное состояние, является правильным подходом. – paercebal 2016-10-11 21:05:52

+0

Это может быть, что потребует от вас виртуальных «getters» в базовом классе для доступа к нему. И хотя вы можете иметь промежуточные классы для разных способов реализации шаблона данных, это не всегда удобно. Например, «шаблон», распространенный на языках, которые не имеют модификатора «const», хотя и не обязательно большую часть времени на C++, должен иметь базовый класс только для чтения и записываемые производные классы. В C++ это также может быть приятным просто потому, что вы хотите более одного возможного способа загрузки (инициализации) данных. – CashCow 2016-10-13 08:53:32

8

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

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

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

3

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

2

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

0

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

  • указателя на прямо или косвенно производный класс
  • ссылка на прямо или косвенно производный класс
  • объекта из прямо или косвенно производного класса
2

Private: это спецификатор доступа. По умолчанию переменные экземпляра (члена) или методы класса в C++/java являются закрытыми. Во время наследования код и данные всегда унаследованы, но недоступны вне класса. Мы можем объявить наших членов данных конфиденциальными, чтобы никто не мог вносить непосредственные изменения в наши переменные-члены, и мы можем предоставлять публичные получатели и сеттеры для изменения наших частных членов. И эта концепция всегда применяется в бизнес-правиле.

Защищенный: он также является спецификатором доступа. В C++ защищенные члены доступны внутри класса и унаследованного класса, но не вне класса. В java защищенные члены доступны внутри класса, унаследованного класса, а также для всех классов в одном пакете.

0

частные и защищенные модификаторы доступа являются одними и теми же, только защищенные члены базового класса могут быть доступны за пределами основного класса в дочернем (производном) классе. Он также применяется к наследованию. Но с частным модификатором члены базового класса могут быть доступны только в области или код базового класса и его друг функции только «» «»

3

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

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

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

Смежные вопросы