Вызов вирутальной приватной функции
От: LowCoder  
Дата: 22.04.11 18:12
Оценка: :))
Тут меня спросили что будет если объявить виртуальную функцию приватной. Я подумал и решил что либо она будет недоступна дибо вызовится функция базового класса. Оказалось что нет!

Вот кодик


#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();
}



Вывод: Class B



Вопрос — а пааачему? (компилятор gc++)
Re: Вызов вирутальной приватной функции
От: dudkin  
Дата: 22.04.11 18:21
Оценка:
Здравствуйте, LowCoder, Вы писали:

LC>Тут меня спросили что будет если объявить виртуальную функцию приватной. Я подумал и решил что либо она будет недоступна дибо вызовится функция базового класса. Оказалось что нет!

LC>Вопрос — а пааачему? (компилятор gc++)

приватности они компилятором отсеиваются с ошибкой "error C2248: cannot access private member declared in class"
если посмотреть на код то все нормально у A::f() — доступна . она же паблик!
а вот при исполнении на приватность никто не проверяет (поздно уже) и дальше работает стандартный механизм виртуальных функцтй
Re: Вызов вирутальной приватной функции
От: andrey_nado  
Дата: 22.04.11 18:26
Оценка:
Здравствуйте, LowCoder, Вы писали:

http://alenacpp.blogspot.com/2005/08/blog-post.html
Re[2]: Вызов вирутальной приватной функции
От: LowCoder  
Дата: 22.04.11 19:02
Оценка:
Здравствуйте, andrey_nado, Вы писали:

_>Здравствуйте, LowCoder, Вы писали:


_>http://alenacpp.blogspot.com/2005/08/blog-post.html


Я прочитал Аленин пост но у меня по её не получилось. Я не могу сейчас на майрософтовском компиляторе проверить (я логично предполагаю в майкрософтах пользуют именно его но у меня в унихах на 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
Re: Вызов вирутальной приватной функции
От: Ytz https://github.com/mtrempoltsev
Дата: 22.04.11 19:23
Оценка:
Здравствуйте, LowCoder, Вы писали:

LC>Вопрос — а пааачему? (компилятор gc++)


Работает это потому, что в базовом классе функция объявлена как public и вызов идет через указатель на базовый класс. Поставь вместо A* B* при создании объекта и компилятор даст по рукам.

Теперь где закрытые виртуальные функции будут полезны. Есть такое понятие как non virtual interface, то есть сокрытие виртуальных вызовов за фасадом из невиртуальной функции. Это дает определенную гибкость в изменении, позволяет задать определенный порядок выполнения и добавить некоторые проверки:

class DataSource
{
public:
    char* GetData()
    {
        if (!Open()) { ... }
        Data* data = Read();
        if (!data) { ... }
        if (!Close()) { ... }
        return data;
    }
private:
    virtual bool Open() = 0;
    virtual Data* Read() = 0;
    virtual bool Close() = 0;
};


class FileSource : public DataSource
{
private:
    virtual void OpenDataSource()
    { ... }
    virtual Data* ReadData()
    { ... }
    virtual void CloseDataSource()
    { ... }
};

class DataBaseSource : public DataSource
{
private:
    virtual void OpenDataSource()
    { ... }
    virtual Data* ReadData()
    { ... }
    virtual void CloseDataSource()
    { ... }
};
Re[3]: Вызов вирутальной приватной функции
От: diver_ru  
Дата: 22.04.11 19:26
Оценка:
Здравствуйте, LowCoder, Вы писали:

LC>Я прочитал Аленин пост но у меня по её не получилось. Я не могу сейчас на майрософтовском компиляторе проверить (я логично предполагаю в майкрософтах пользуют именно его но у меня в унихах на g++ не забалуешь


У нее нигде и не написано, что приватную функцию напрямую можно вызывать
Re[4]: Вызов вирутальной приватной функции
От: LowCoder  
Дата: 22.04.11 19:50
Оценка:
Здравствуйте, diver_ru, Вы писали:

_>Здравствуйте, LowCoder, Вы писали:


LC>>Я прочитал Аленин пост но у меня по её не получилось. Я не могу сейчас на майрософтовском компиляторе проверить (я логично предполагаю в майкрософтах пользуют именно его но у меня в унихах на g++ не забалуешь


_>У нее нигде и не написано, что приватную функцию напрямую можно вызывать


Ну я так понимаю что у неё это компилируется раз и как раз вызывается именно ведь таким сопособом она в своей статье делает что бы в каждом классе был свой id. Я по крайне мере понял это именно так.
Re[5]: Вызов вирутальной приватной функции
От: Ops Россия  
Дата: 22.04.11 19:59
Оценка: +1
Здравствуйте, LowCoder, Вы писали:

LC>Здравствуйте, diver_ru, Вы писали:


_>>Здравствуйте, LowCoder, Вы писали:


LC>>>Я прочитал Аленин пост но у меня по её не получилось. Я не могу сейчас на майрософтовском компиляторе проверить (я логично предполагаю в майкрософтах пользуют именно его но у меня в унихах на g++ не забалуешь


_>>У нее нигде и не написано, что приватную функцию напрямую можно вызывать


LC>Ну я так понимаю что у неё это компилируется раз и как раз вызывается именно ведь таким сопособом она в своей статье делает что бы в каждом классе был свой id. Я по крайне мере понял это именно так.


Она в своих статьях никогда не приводит серьезного кода. А философия — да, философия.
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
Re[3]: Вызов вирутальной приватной функции
От: andrey_nado  
Дата: 22.04.11 20:11
Оценка:
Здравствуйте, LowCoder, Вы писали:

Код в качестве иллюстрации:

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, хотя он закрытый. Другими словами, возможность переопределить виртуальный метод никак не связана с видимостью этого метода.
c++ virtual
Re[4]: Вызов вирутальной приватной функции
От: dudkin  
Дата: 22.04.11 20:16
Оценка:
Здравствуйте, andrey_nado, Вы писали:


_>Смысл поста Алёны в том, класс B может перекрывать виртуальный метод foo, хотя он закрытый. Другими словами, возможность переопределить виртуальный метод никак не связана с видимостью этого метода.


"закрытость" это игры для языка верхнего уровня С++
если очень надо то функцию можно вызвать через виртуальную таблицу без всяких friend
Re: Вызов вирутальной приватной функции
От: MasterZiv СССР  
Дата: 24.04.11 06:06
Оценка:
On 22.04.2011 22:12, LowCoder wrote:

> Тут меня спросили что будет если объявить виртуальную функцию приватной. Я

> подумал и решил что либо она будет недоступна дибо вызовится функция базового
> класса. Оказалось что нет!

Эту виртуальную функцию и её переопределения можно будет вызывать только
из этого класса, где она определена. Плюс наследники в своих реализациях
не смогут перевызывать эту функцию из базового класса.
Posted via RSDN NNTP Server 2.1 beta
Re[5]: Вызов вирутальной приватной функции
От: diver_ru  
Дата: 25.04.11 07:34
Оценка:
Здравствуйте, LowCoder, Вы писали:

LC>Здравствуйте, diver_ru, Вы писали:


_>>У нее нигде и не написано, что приватную функцию напрямую можно вызывать


LC>Ну я так понимаю что у неё это компилируется раз и как раз вызывается именно ведь таким сопособом она в своей статье делает что бы в каждом классе был свой id. Я по крайне мере понял это именно так.


Стоп, стоп. А где она там функцию getID вызывает вне класса CBase? Ясен перец, компилятор непотребство в виде прямого вызова приватной функции не допустит.
Идея в том, что
>вы хотите, чтобы функция была переопределена в наследнике, но чтобы нельзя было вызвать функцию базового класса.
Т.е. функция вызывается только в реализации CBase и нигде более.
Re: Вызов вирутальной приватной функции
От: stapter  
Дата: 27.04.11 08:10
Оценка: 14 (1) :)
Меня это как-то тоже немного удивило, но товарищ Erop, очень четко все расписал вот здесь http://rsdn.ru/forum/cpp/3746675.1.aspx
Автор: Erop
Дата: 23.03.10

Вот если б все так доходчиво объясняли!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.