Тут меня спросили что будет если объявить виртуальную функцию приватной. Я подумал и решил что либо она будет недоступна дибо вызовится функция базового класса. Оказалось что нет!
Вот кодик
#include <iostream>
using namespace std;
class A
{
public:
virtual void f()
{
cout << "Class A" << endl;
}
};
class B: public A
{
private:
virtual void f()
{
cout << "Class B" << endl;
}
};
int main(int argc, char** argv)
{
A *a = new B;
a->f();
}
Здравствуйте, LowCoder, Вы писали:
LC>Тут меня спросили что будет если объявить виртуальную функцию приватной. Я подумал и решил что либо она будет недоступна дибо вызовится функция базового класса. Оказалось что нет! LC>Вопрос — а пааачему? (компилятор gc++)
приватности они компилятором отсеиваются с ошибкой "error C2248: cannot access private member declared in class"
если посмотреть на код то все нормально у A::f() — доступна . она же паблик!
а вот при исполнении на приватность никто не проверяет (поздно уже) и дальше работает стандартный механизм виртуальных функцтй
Я прочитал Аленин пост но у меня по её не получилось. Я не могу сейчас на майрософтовском компиляторе проверить (я логично предполагаю в майкрософтах пользуют именно его но у меня в унихах на g++ не забалуешь
#include <iostream>
using namespace std;
class A
{
private:
virtual void f() = 0;
};
class B: public A
{
private:
void f()
{
cout << "Class B" << endl;
}
};
int main(int argc, char** argv) {
A *a = new B;
a->f();
return 0;
}
Compiler error:
main.cpp:22: error: ‘virtual void A::f()’ is private
Здравствуйте, LowCoder, Вы писали:
LC>Вопрос — а пааачему? (компилятор gc++)
Работает это потому, что в базовом классе функция объявлена как public и вызов идет через указатель на базовый класс. Поставь вместо A* B* при создании объекта и компилятор даст по рукам.
Теперь где закрытые виртуальные функции будут полезны. Есть такое понятие как non virtual interface, то есть сокрытие виртуальных вызовов за фасадом из невиртуальной функции. Это дает определенную гибкость в изменении, позволяет задать определенный порядок выполнения и добавить некоторые проверки:
Здравствуйте, LowCoder, Вы писали:
LC>Я прочитал Аленин пост но у меня по её не получилось. Я не могу сейчас на майрософтовском компиляторе проверить (я логично предполагаю в майкрософтах пользуют именно его но у меня в унихах на g++ не забалуешь
У нее нигде и не написано, что приватную функцию напрямую можно вызывать
Здравствуйте, diver_ru, Вы писали:
_>Здравствуйте, LowCoder, Вы писали:
LC>>Я прочитал Аленин пост но у меня по её не получилось. Я не могу сейчас на майрософтовском компиляторе проверить (я логично предполагаю в майкрософтах пользуют именно его но у меня в унихах на g++ не забалуешь
_>У нее нигде и не написано, что приватную функцию напрямую можно вызывать
Ну я так понимаю что у неё это компилируется раз и как раз вызывается именно ведь таким сопособом она в своей статье делает что бы в каждом классе был свой id. Я по крайне мере понял это именно так.
Здравствуйте, LowCoder, Вы писали:
LC>Здравствуйте, diver_ru, Вы писали:
_>>Здравствуйте, LowCoder, Вы писали:
LC>>>Я прочитал Аленин пост но у меня по её не получилось. Я не могу сейчас на майрософтовском компиляторе проверить (я логично предполагаю в майкрософтах пользуют именно его но у меня в унихах на g++ не забалуешь
_>>У нее нигде и не написано, что приватную функцию напрямую можно вызывать
LC>Ну я так понимаю что у неё это компилируется раз и как раз вызывается именно ведь таким сопособом она в своей статье делает что бы в каждом классе был свой id. Я по крайне мере понял это именно так.
Она в своих статьях никогда не приводит серьезного кода. А философия — да, философия.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
class A {
virtual void foo() = 0;
public:
void bar() {
foo(); // вызов чистой виртуальной функции
}
};
class B : public A{
virtual void foo() {
std::cout << "B::foo" << std::endl;
}
};
int main() {
A *a = new B();
a->bar();
return 0;
}
Смысл поста Алёны в том, класс B может перекрывать виртуальный метод foo, хотя он закрытый. Другими словами, возможность переопределить виртуальный метод никак не связана с видимостью этого метода.
_>Смысл поста Алёны в том, класс B может перекрывать виртуальный метод foo, хотя он закрытый. Другими словами, возможность переопределить виртуальный метод никак не связана с видимостью этого метода.
"закрытость" это игры для языка верхнего уровня С++
если очень надо то функцию можно вызвать через виртуальную таблицу без всяких friend
On 22.04.2011 22:12, LowCoder wrote:
> Тут меня спросили что будет если объявить виртуальную функцию приватной. Я > подумал и решил что либо она будет недоступна дибо вызовится функция базового > класса. Оказалось что нет!
Эту виртуальную функцию и её переопределения можно будет вызывать только
из этого класса, где она определена. Плюс наследники в своих реализациях
не смогут перевызывать эту функцию из базового класса.
Здравствуйте, LowCoder, Вы писали:
LC>Здравствуйте, diver_ru, Вы писали:
_>>У нее нигде и не написано, что приватную функцию напрямую можно вызывать
LC>Ну я так понимаю что у неё это компилируется раз и как раз вызывается именно ведь таким сопособом она в своей статье делает что бы в каждом классе был свой id. Я по крайне мере понял это именно так.
Стоп, стоп. А где она там функцию getID вызывает вне класса CBase? Ясен перец, компилятор непотребство в виде прямого вызова приватной функции не допустит.
Идея в том, что >вы хотите, чтобы функция была переопределена в наследнике, но чтобы нельзя было вызвать функцию базового класса.
Т.е. функция вызывается только в реализации CBase и нигде более.