Частные и защищенные члены

Мне сложно понять разницу между закрытыми и защищенными членами в классе C ++. Говоря простым языком, в чем разница?


person Maxpm    schedule 12.01.2011    source источник


Ответы (3)


protected члены доступны производным классам. private участников нет.

Обычно (в большинстве случаев) участники должны быть private или public. Редко и необычно требуется protected член (редактировать) в хорошо спроектированной системе.

РЕДАКТИРОВАТЬ:

Может быть, мне стоит уточнить, почему protected участников могут быть запахом кода.

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

Другие подробно остановились на этом.

Вот что говорит Страуструп в своем тексте:

Участники, объявленные защищенными, гораздо более уязвимы для злоупотреблений, чем участники, объявленные закрытыми. В частности, объявление защищенных элементов данных обычно является ошибкой проектирования. Размещение значительных объемов данных в общем классе для использования всеми производными классами оставляет эти данные открытыми для повреждения. Хуже того, защищенные данные, такие как общедоступные, не могут быть легко реструктурированы, потому что нет хорошего способа найти любое применение. Таким образом, защищенные данные становятся проблемой обслуживания программного обеспечения.

См. Также этот вопрос.

person John Dibling    schedule 12.01.2011
comment
Что не очень хорошо продумано в использовании protected участников? (Я их постоянно использую - что делаю не так?) - person Kristopher Johnson; 12.01.2011
comment
@Kristopher: См. Мою редакцию. Я уточнил и сделал перекрестные ссылки, пытаясь ответить на ваш вопрос. - person John Dibling; 12.01.2011
comment
В gotw.ca/publications/mill18.htm Саттер говорит, что если производные классы должны вызвать базовую реализацию виртуальной функции, сделать виртуальную функцию защищенной. Так что один эксперт на вашей стороне, а другой - на моей. :) А если серьезно, я просто считаю, что редкость и необычность - это преувеличение. Я бы согласился с необычным, но иногда принятие некоторой связи между базовым и производным классами проще, чем альтернативы. - person Kristopher Johnson; 12.01.2011
comment
Я не думаю, что все, что я сказал, не согласуется с утверждением Саттера, что если вам нужно, чтобы что-то было protected, то это должно быть protected. Но обратите внимание, что даже Саттер сказал в той самой статье, на которую вы ссылаетесь, что те же самые виртуальные методы должны быть private по умолчанию. - person John Dibling; 12.01.2011
comment
Я думаю, мы в основном согласны; просто у нас разные значения слова «редкий». - person Kristopher Johnson; 12.01.2011
comment
Перечитывая ваш ответ, я теперь замечаю, что ваше уточнение касается членов данных. Я полностью согласен с тем, что члены данных никогда / редко должны создаваться protected. Мои комментарии действительно касаются членов-функций. - person Kristopher Johnson; 12.01.2011
comment
Да, я говорил о членах data. Хотя я этого не понимал. - person John Dibling; 12.01.2011

Из часто задаваемых вопросов по C ++:

  • Член (член данных или функция-член), объявленный в закрытом разделе класса, может быть доступен только функциям-членам и друзьям этого класса.
  • Член (член данных или функция-член), объявленный в защищенном разделе класса, может быть доступен только функциям-членам и друзьям этого класса, а также функциям-членам и друзьям производных классов.
  • Член (член данных или функция-член), объявленный в общедоступном разделе класса, может быть доступен любому.
person Mark Loeser    schedule 12.01.2011

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

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

Простой пример:

class Base
{
protected:
    int prot;

private:
    int priv;

public:
    int Prot() const { return prot; }
    int Priv() const { return priv; }
};

class Derived
{
public:
    void ShowProt() { cout << prot; }  // OK - prot is accessible because it is protected
    void ShowPriv() { cout << priv; }  // Compile Error - cannot access priv, which is private
    void ShowPriv2() { cout << Priv(); } // OK, because Priv() is public
};
person Kristopher Johnson    schedule 12.01.2011
comment
Также обратите внимание, что друзья могут получить доступ к защищенным участникам. - person Daniel Gallagher; 12.01.2011