Virtual and Pure Virtual function
От: MT  
Дата: 25.08.03 13:27
Оценка:
Д. день!

Чем отличается виртуальная функция от чистой виртуальной функции?
На примере двух классов:

class Shape { virtual void draw(); }

class Shape2 { virtual void draw() = 0; }
Быстрее, лучше, дешевле — выбери любые два.
(Старая инженерная поговорка)
Re: Virtual and Pure Virtual function
От: Ed.ward Россия  
Дата: 25.08.03 13:29
Оценка:
Здравствуйте, MT, Вы писали:

MT>Д. день!


MT>Чем отличается виртуальная функция от чистой виртуальной функции?

MT>На примере двух классов:

MT>
MT>class Shape { virtual void draw(); }

MT>class Shape2 { virtual void draw() = 0; }
MT>


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

Ed.ward
... << RSDN@Home 1.0 beta 7a >>
Re: Virtual and Pure Virtual function
От: Dmi3evS Россия http://dmi3s.blogspot.com/
Дата: 25.08.03 13:31
Оценка:
Здравствуйте, MT, Вы писали:

MT>Д. день!


MT>Чем отличается виртуальная функция от чистой виртуальной функции?

MT>На примере двух классов:

MT>
MT>class Shape { virtual void draw(); }

MT>class Shape2 { virtual void draw() = 0; }
MT>


Ты не обязан писать тело функции в случае Shape2::draw().
Re: Virtual and Pure Virtual function
От: Всеволод Россия  
Дата: 25.08.03 13:31
Оценка: 2 (1)
Здравствуйте, MT, Вы писали:

MT>Д. день!


MT>Чем отличается виртуальная функция от чистой виртуальной функции?

MT>На примере двух классов:

MT>
MT>class Shape { virtual void draw(); }

MT>class Shape2 { virtual void draw() = 0; }
MT>


Виртуальная функция может быть переопределена в производном классе.
Чисто виртуальная функция должна быть переопределена в производном классе.
Чисто виртуальные функции обычно используют для создания интерфейсных классов.
Re: Virtual and Pure Virtual function
От: Кодт Россия  
Дата: 25.08.03 13:32
Оценка:
Здравствуйте, MT, Вы писали:

MT>Чем отличается виртуальная функция от чистой виртуальной функции?

MT>На примере двух классов:

MT>
MT>class Shape { virtual void draw(); }
// Здесь функция объявлена; предполагается, что ее определение - вне объявления класса.
// Отсутствие определения - вызовет ошибку линковки
// поскольку ссылка на функцию помещена в VMT этого класса

MT>class Shape2 { virtual void draw() = 0; }
// Эту функцию можно не определять (хотя можно и определить).
// А вот VMT с нуллевой ссылкой уже быть не может,
// поэтому создать экземпляр класса Shape2 невозможно
MT>
Перекуём баги на фичи!
Re: Virtual and Pure Virtual function
От: Lorenzo_LAMAS  
Дата: 25.08.03 13:32
Оценка:
Наличие чисто виртуальной функции в твоем классе делает его абстрактным, объекты такого класса нельзя создавать, хотя можно объявить ссылки и указатели. Чисто виртуальная функция может иметь реализацию, только ее нельзя определить в классе.
class Abstract
{
public:
   virtual ~Abstract() = 0;
};

Abstract::~Abstract()
{
}


Если умудриться вызвать такую функцию через ссылку или указатель, т.е. добиться вызова через втбл, то прога грохнется.
А еще очень много всего, но это лучше в книгах умных почитать или поиском пользоваться
Of course, the code must be complete enough to compile and link.
Re[2]: Virtual and Pure Virtual function
От: Аноним  
Дата: 25.08.03 13:33
Оценка:
Здравствуйте, Кодт, Вы писали:

MT>>
MT>>class Shape { virtual void draw(); }
К>// Здесь функция объявлена; предполагается, что ее определение - вне объявления класса.
К>// Отсутствие определения - вызовет ошибку линковки
К>// поскольку ссылка на функцию помещена в VMT этого класса

MT>>class Shape2 { virtual void draw() = 0; }
К>// Эту функцию можно не определять (хотя можно и определить).
К>// А вот VMT с нуллевой ссылкой уже быть не может,

Может, еще как может. Причем возможен даже вызов чисто виртуальной функции.

К>// поэтому создать экземпляр класса Shape2 невозможно
MT>>
Re: Virtual and Pure Virtual function
От: LaptevVV Россия  
Дата: 25.08.03 13:35
Оценка: 1 (1)
Здравствуйте, MT, Вы писали:

MT>Чем отличается виртуальная функция от чистой виртуальной функции?

MT>На примере двух классов:

MT>
MT>class Shape { virtual void draw(); }
MT>class Shape2 { virtual void draw() = 0; }
MT>

Добавлю свои 2 копейки.
Ты можешь создать объект типа Shape, и не можешь — типа Shape2, потому как там чистая виртуальная функция. Получается абстрактный класс, как в Яве.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re: Virtual and Pure Virtual function
От: Анатолий Широков СССР  
Дата: 25.08.03 13:36
Оценка:
Наличие виртуальной функции делает класс полиморфным, чисто виртуальная функция делает класс не только полиморным, но и абстрактным.
Re: Virtual and Pure Virtual function
От: MT  
Дата: 25.08.03 13:40
Оценка:
Спасибо всем.

Но есть противоречивые ответы...
Поэтому уточните пожалуста — должен ли я определять чисто виртуальную функциу в производном классе, или можно не определять?

MT>Д. день!


MT>Чем отличается виртуальная функция от чистой виртуальной функции?

MT>На примере двух классов:

MT>
MT>class Shape { virtual void draw(); }

MT>class Shape2 { virtual void draw() = 0; }
MT>
Быстрее, лучше, дешевле — выбери любые два.
(Старая инженерная поговорка)
Re[3]: Virtual and Pure Virtual function
От: LaptevVV Россия  
Дата: 25.08.03 13:42
Оценка:
Здравствуйте, Аноним, Вы писали:

MT>>>class Shape2 { virtual void draw() = 0; }

К>>// Эту функцию можно не определять (хотя можно и определить).
К>>// А вот VMT с нуллевой ссылкой уже быть не может,

А>Может, еще как может. Причем возможен даже вызов чисто виртуальной функции.

Это что за компилер такой?
VC6 — не создает!
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[2]: Virtual and Pure Virtual function
От: Аноним  
Дата: 25.08.03 13:46
Оценка: 3 (2)
Здравствуйте, MT, Вы писали:

MT>Но есть противоречивые ответы...

MT>Поэтому уточните пожалуста — должен ли я определять чисто виртуальную функциу в производном классе, или можно не определять?

Если у тебя в классе есть чисто виртуальные функции, то класс является абстрактным; если в потомке абстрактного класса переопределены не все функции, являющиеся в классе-предке чисто виртуальными, то этот класс-потомок также абстрактный.

Класс не является абстрактным, только если в нем нет ни собственных ЧВФ, ни непереопределенных ЧВФ, "оставшихся в наследство" от класса-предка.
Re[4]: Virtual and Pure Virtual function
От: Lorenzo_LAMAS  
Дата: 25.08.03 13:48
Оценка:
Это очень легко сделать. Деструктор абстрактной базы установит вптр на таблицу абстрактной базы,которая содержит некоторую заглушку. Вызови в деструкторе абстрактной базы функцию, которая вызывает чисто виртуальную функцию и ага.
Of course, the code must be complete enough to compile and link.
Re[5]: Virtual and Pure Virtual function
От: LaptevVV Россия  
Дата: 25.08.03 13:52
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Это очень легко сделать. Деструктор абстрактной базы установит вптр на таблицу абстрактной базы,которая содержит некоторую заглушку. Вызови в деструкторе абстрактной базы функцию, которая вызывает чисто виртуальную функцию и ага.

Не, ну понятно, что обойти можно все, что угодно!
Мы-то говорим о стандартных средствах языка!
И вопрос так ставился изначально. А потом чел пишет вдруг, что у него создает.
Так пусть приведет, как стандарт обходит.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[4]: Virtual and Pure Virtual function
От: Аноним  
Дата: 25.08.03 13:56
Оценка:
Здравствуйте, LaptevVV, Вы писали:

А>>Может, еще как может. Причем возможен даже вызов чисто виртуальной функции.

LVV>Это что за компилер такой?
LVV>VC6 — не создает!

Создает.

class b;

void g(b*);

class b
{
public:
    b()
    {
        g(this);
    }

    virtual void f() = 0;
};

class d : public b
{
public:
    void f()
    {}
};

void g(b* bb)
{
    bb->f();
}

int main()
{
    d dd; // Наслаждаемся эффектом!

    return 0;
}
Re[6]: Virtual and Pure Virtual function
От: Lorenzo_LAMAS  
Дата: 25.08.03 13:56
Оценка:
Кодт говорит, что не может быть VMT с нулевой ссылкой, Аноним говорит, что может — т.е. для абстрактного класса создается VMT. Я согласен с Анонимом, и пример, который я привел, это показывает (по-моему)
Of course, the code must be complete enough to compile and link.
Re[4]: Virtual and Pure Virtual function
От: Аноним  
Дата: 25.08.03 14:05
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>VC6 — не создает!


Кстати, именно VC6 грешит тем, что позволяет создавать временные объекты абстрактных типов.
Re[5]: Virtual and Pure Virtual function
От: LaptevVV Россия  
Дата: 25.08.03 14:08
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Создает.

Пардон-с!!! Где ж тут создание есть создание объекта абстракного класса?
Смотри в коде комментарии
А>
А>class b;
А>void g(b*);
А>class b
А>{
А>public:
А>    b(){g(this);}
А>    virtual void f() = 0;    //чисто виртуальная
А>};

А>class d : public b             //наследник 
А>{
А>public:
А>    void f(){}               //а вот и реализация!!!!!
А>};

А>void g(b* bb)
А>{
    bb->>f();
А>}

А>int main()
А>{
А>    d dd; // Пардон!! Создали не из абстрактного класса
А>    return 0;
А>}
А>

Ну и что, что тело пустое у функции в наследнике — это все равно реализация! Так что создал ты нормальный объект.
А в функции g у тебя не объект, а указатель на объект. А это можно.
А ты вызвал бы g и посмотрел, что получается.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[6]: Virtual and Pure Virtual function
От: Lorenzo_LAMAS  
Дата: 25.08.03 14:12
Оценка:
Вы не о том. А о чем Аноним и лоренцо — смотри выше в моем примере. Кроме того, вижуал действительно позволяет создавать объект абстрактного класса (если я ничего не путаю) — тут как-то об этом говорили, может Аноним подробнее скажет
Of course, the code must be complete enough to compile and link.
Re[7]: Virtual and Pure Virtual function
От: LaptevVV Россия  
Дата: 25.08.03 14:26
Оценка:
Здравствуйте, Lorenzo_LAMAS, Вы писали:

L_L>Кодт говорит, что не может быть VMT с нулевой ссылкой, Аноним говорит, что может — т.е. для абстрактного класса создается VMT. Я согласен с Анонимом, и пример, который я привел, это показывает (по-моему)

Если б я реализовывал, то конечно создавал бы. Наследовать потом проще. Разве что указатели оставлять нулевые, подчеркивая абстрактность. Наверное, они так же рассуждали.
Но, уважаемый Lorenzo, поясните мне неучу, почему аноним считает (и приводит пример), что абстрактный объект создается.
Я откомеентарил — у него ж там все от наследника. Указатель в функции g — так указатель вроде не запрещается создавать даже на
class aaa;
aaa *p;

а уж у него вообще класс определен.
Что я непонимаю?
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.