Спецификаторы доступа и виртуальные функции - PullRequest
2 голосов
/ 24 сентября 2010

Каковы правила доступности, когда виртуальные функции объявлены в 3 различных спецификаторах доступа, указанных в C ++ (открытый, закрытый, защищенный) Каково значение каждого? Любые простые примеры кода, объясняющие эту концепцию, будут очень полезны.

Ответы [ 2 ]

10 голосов
/ 24 сентября 2010

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

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

Если поиск имени определяет жизнеспособную функцию как виртуальную функцию, спецификатор доступа к виртуальной функции проверяется в рамках статического типа выражения объекта, используемого для именования функции. Во время выполнения фактическая вызываемая функция может быть определена в производном классе с совершенно другим спецификатором доступа. Это потому, что «спецификаторы доступа» являются явлением времени компиляции.

// Brain compiled code ahead
struct A{
   virtual void f() {}
private:
   virtual void g() {}
protected:
   virtual void h() {}
};

struct B : A{
private:
   virtual void f() {}           // Allowed, but not a good habit I guess!
};

B b;
A &ra = b;

ra.f();    // name lookup of 'f' is done in 'A' and found to be public. Compilation 
           // succeeds and the call is dynamically bound
           // At run time the actual function to be called is 'B::f' which could be private, protected etc but that does not matter
0 голосов
/ 24 сентября 2010

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

Подводя итог, можно сказать:

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

Public - это интерфейс, а частные / защищенные функции - это внутренние компоненты.Также обратите внимание, что все локальные переменные (в соответствии с инкапсулизмом) должны быть защищены / приватны.

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

class A : [public | protected | private] B
{
};

спецификатор public / private / protected перед B указывает наименее ограничивающий уровень безопасности для наследования от базового класса.Это не «фильтр» для методов и локальных переменных в том смысле, что некоторые не наследуются, он просто меняет уровень безопасности на указанный, если они менее ограничены (более общедоступны).

Итакclass A : public B оставит унаследованных базовых членов такими, какие они есть, class A : private B изменит их всех на частных.

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

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