logo
шпоры по ООП

22.Ограничения на использование виртуальных функций.

#include <string>

using namespace std;

class A

{

public:

A( const string& s ) { /* ... */ }

string foo()

{

bar();

return "Строка";

}

virtual void bar()

{

} };

class B : public A

{

public:

B() : A( s = foo() ) {}

private:

string s;

};

int main()

{ B b;

return 0; }

Компилятор берет указатель this, получает указатель на таблицу виртуальных функций, считывает из нее адрес метода bar() и выполняет вызов. Указатель this указывает на объект B, который еще не был создан. Т.е. у него указатель на таблицу виртуальных функций содержит "мусор"!Поэтому приведенный код с высокой долей вероятности вызовет крах системы, и уж точно он не будет делать то, что задумывалось.

САМОЕ ОСНОВНОЕ :Инициализация указателя таблицы виртуальных функций выполняется в конструкторе (перед инициализацией членов класса, но после вызова конструкторов родительских классов). Это накладывает существенное ограничение на использование виртуальных функций при инициализации. Думаю, что на основании этого материала, вы сами сможете промоделировать, как будут работать косвенные вызовы на разных этапах инициализации объекта.