2013-07-22 3 views
0
#include <iostream> 
using namespace std; 

class B 
{ 
    B(); 

public: 
    virtual void print()=0; 
}; 

void B::print() 
{ 
    cout << "B::print"; 
} 

int main() 
{ 
    B *bp; 
    bp->B::print(); /* Type-A works fine */ 
    bp->print();  /* Type-B segmentation fault */ 

    return 0; 
} 

В приведенном выше коде я пытаюсь использовать чистую виртуальную функцию через 'bp'. Теперь в основной функции есть два типа вызова (Тип-A, Тип-B). Мой вопрос в том, почему A работает, но B нет. Более того, почему компилятор позволяет вызывать нестационарную функцию без создания объекта.Странное поведение чистой виртуальной функции

+0

Re: "* почему компилятор позволяет вызывать нестационарную функцию без создания объекта. *" Поскольку компилятор предполагает, что вы знаете, что делаете. У компилятора нет простого способа проверить, что 'bp' указывает на что-то действительное в общем случае. –

+0

В зависимости от вашего уровня предупреждения вы должны увидеть что-то вроде 'warning C4700: неинициализированная локальная переменная 'bp' used'. – Derek

ответ

4

Оба являются неопределенным поведением, и все может случиться. bp не инициализирован, поэтому вызов методов на нем или разыменование его является незаконным.

5

bp не указывает на действительный объект, так что вы испытываете неопределенное поведение. В этом случае A works but B doesn't является совершенно допустимым неопределенным поведением. Обратите внимание, что вы не можете сделать bp, указывая на объект типа B, потому что это абстрактный тип. Если вы вывели другой класс и внедрили print, тогда вы можете указать bp на этот дочерний объект.

1

Точка:

  1. bp->B::print() может работать, потому что: B::print() будет дано Явно и имеет действительный указатель, а сама функция не включает в себя с *this указателем. Он будет переведен в B::print(bp), а bp пренебрегают.

  2. bp->print() не может работать, потому что код будет выглядеть для vptr объекта bp точки к, не существует. vptr дает неправильное положение vtable, и вызов функции не будет выполнен. Он переводится на sth. подобный: bp->vptr->vtable['print'](bp)' and you can see both vptr and vtable` не определен.

Смежные вопросы