Re[2]: Virtual and Pure Virtual function
От: Аноним  
Дата: 25.08.03 13:46
Оценка: 3 (2)
Здравствуйте, MT, Вы писали:

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

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

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

Класс не является абстрактным, только если в нем нет ни собственных ЧВФ, ни непереопределенных ЧВФ, "оставшихся в наследство" от класса-предка.
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
От: 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[10]: Virtual and Pure Virtual function
От: Другой Аноним  
Дата: 25.08.03 14:52
Оценка: :)
Здравствуйте, LaptevVV, Вы писали:

LVV>А вы ТОТ аноним?


Тот самый.
Re[12]: Virtual and Pure Virtual function
От: Другой Аноним  
Дата: 25.08.03 14:58
Оценка: :)
Здравствуйте, LaptevVV, Вы писали:

LVV>А абстрактный объект в явном виде по стандарту создать нельзя. И мои компиляторы в этом месте соответствуют.


А вы и компиляторы выпускаете?
Re[6]: Virtual and Pure Virtual function
От: Кодт Россия  
Дата: 26.08.03 07:35
Оценка: +1
Здравствуйте, LaptevVV, Вы писали:

LVV>Здравствуйте, Аноним, Вы писали:


LVV>Пардон-с!!! Где ж тут создание есть создание объекта абстракного класса?


В конструкторе абстрактного класса
class A
{
public:
  virtual void pure() = 0;
  void call_pure()
  {
    pure();
  }

  A() // vfptr = &A::vmt
  {
    pure(); // здесь - статический вызов;
            // если функция не определена, линкер ошибет.
    call_pure(); // здесь - динамический вызов;
                 // поскольку в VMT класса A неизвестно что, то будет undefined behaviour
                 // (вероятнее всего, там ссылка на функцию выброса исключения)
  }
};

class B : public A
{
public:
  virtual void pure() { ; }

  B()
    : A() // vfptr = &A::vmt
    // vfptr = &B::vmt
  {
    pure();
    call_pure(); // в данный момент используем уже VMT класса B
  }
};

int main()
{
  B b;

  return 0;
}
Перекуём баги на фичи!
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: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
От: Анатолий Широков СССР  
Дата: 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[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;

а уж у него вообще класс определен.
Что я непонимаю?
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[8]: Virtual and Pure Virtual function
От: Аноним  
Дата: 25.08.03 14:30
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>Но, уважаемый Lorenzo, поясните мне неучу, почему аноним считает (и приводит пример), что абстрактный объект создается.


Я так не считаю и примера такого не привожу.
Re[6]: Virtual and Pure Virtual function
От: Аноним  
Дата: 25.08.03 14:31
Оценка:
Здравствуйте, LaptevVV, Вы писали:

LVV>Пардон-с!!! Где ж тут создание есть создание объекта абстракного класса?


Нигде. А что, кто-то утверждал, что есть?
Re[9]: Virtual and Pure Virtual function
От: LaptevVV Россия  
Дата: 25.08.03 14:37
Оценка:
Здравствуйте, Аноним, Вы писали:

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


LVV>>Но, уважаемый Lorenzo, поясните мне неучу, почему аноним считает (и приводит пример), что абстрактный объект создается.


А>Я так не считаю и примера такого не привожу.

А вы ТОТ аноним?
Значит, пример доказывал создание VMT с нулевой ссылкой, да?
Если так, то и пусть себе. Это, ИМХО, нормально. Я так бы тож делал.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[10]: Virtual and Pure Virtual function
От: MT  
Дата: 25.08.03 14:46
Оценка:
Vot, nashel koe chto:

Incidentally, it is possible to provide a definition for a pure virtual function. That is, you could provide an implementation for Shape::draw, and C++ wouldn't complain, but the only way to call it would be to fully specify the call with the class name: ¤ Item E36, P11

Shape *ps = new Shape;           // error! Shape is abstract
Shape *ps1 = new Rectangle;      // fine
ps1->draw();                     // calls Rectangle::draw
Shape *ps2 = new Ellipse;        // fine
ps2->draw();                     // calls Ellipse::draw
ps1->Shape::draw();              // calls Shape::draw
ps2->Shape::draw();              // calls Shape::draw


LVV>Здравствуйте, Аноним, Вы писали:


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


LVV>>>Но, уважаемый Lorenzo, поясните мне неучу, почему аноним считает (и приводит пример), что абстрактный объект создается.


А>>Я так не считаю и примера такого не привожу.

LVV>А вы ТОТ аноним?
LVV>Значит, пример доказывал создание VMT с нулевой ссылкой, да?
LVV>Если так, то и пусть себе. Это, ИМХО, нормально. Я так бы тож делал.
Быстрее, лучше, дешевле — выбери любые два.
(Старая инженерная поговорка)
Re[11]: Virtual and Pure Virtual function
От: LaptevVV Россия  
Дата: 25.08.03 14:53
Оценка:
Здравствуйте, MT, Вы писали:

MT>Incidentally, it is possible to provide a definition for a pure virtual function. That is, you could provide an implementation for Shape::draw, and C++ wouldn't complain, but the only way to call it would be to fully specify the call with the class name: ¤ Item E36, P11

MT>

MT>Shape *ps = new Shape;           // error! Shape is abstract
MT>Shape *ps1 = new Rectangle;      // fine
ps1->>draw();                     // calls Rectangle::draw
MT>Shape *ps2 = new Ellipse;        // fine
ps2->>draw();                     // calls Ellipse::draw
ps1->>Shape::draw();              // calls Shape::draw
ps2->>Shape::draw();              // calls Shape::draw
MT>

Кажется я эту книжку читал!
Но это я и сам знаю, я проверил же пример анонима. Просто я не обратил внимание на фразу Кодта, о том, что vmt не создается из-за нулевых ссылок. А сыр-бор шел как раз вокруг этого. То есть там под ковром абстрактный объект неявно существует.
А абстрактный объект в явном виде по стандарту создать нельзя. И мои компиляторы в этом месте соответствуют.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[13]: Virtual and Pure Virtual function
От: LaptevVV Россия  
Дата: 25.08.03 15:01
Оценка:
Здравствуйте, Другой Аноним, Вы писали:

ДА>Здравствуйте, LaptevVV, Вы писали:


LVV>>А абстрактный объект в явном виде по стандарту создать нельзя. И мои компиляторы в этом месте соответствуют.


ДА> А вы и компиляторы выпускаете?

Могем! Ось, помнится, написали, могем и компилер слабать. Токмо пока не про С++, а просто С. В С++ плюсов много, одному не поднять.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[14]: Virtual and Pure Virtual function
От: Lorenzo_LAMAS  
Дата: 26.08.03 07:16
Оценка:
Кстати, по поводу создания объектов абстрактных классов. Посмотрите такое (у меня сейчас нету под рукой VC6.0 — кто-то как-то на такое вроде жаловался):
//ill-formed program
class Abstr
{
public:
    virtual void fun()const = 0;
};

class NonAbstr:public Abstr
{
public:
     void fun()const{}
};

NonAbstr fun()
{
    return NonAbstr();
}

void LajaFun()
{
    const Abstr & rbase = fun();

    throw rbase;
}


Если не ошибаюсь, вижуал такое компилит — правда, как и что там дальше я не знаю.
Of course, the code must be complete enough to compile and link.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.