Разрешение виртуальной функции не может найти функцию в классе
который не был построен. (Формально: динамический тип
объект - это конструктор или деструктор, который работает.)
вам нужен какой-то пост-конструктор, который язык не делает
поддержка.
Вы можете обойти это, используя фиктивный параметр, который вызывает
функция, которая вам нужна в деструкторе, например ::1003
class Base
{
public:
class PostConstructor
{
Base* owner;
friend class Base;
public:
PostConstructor() : owner( NULL ) {}
~PostConstructor() { owner->parse(); }
};
Base( PostConstructor const& helper )
{
helper.owner = this;
}
};
class Derived : public Base
{
public:
Derived( PostConstructor const& helper = PostConstructor() )
: Base( helper )
{
}
};
или если у класса есть аргументы:
class Base
{
std::string name;
public:
class PostConstructor
{
Base* owner;
std::string arg; // for example...
friend class Base;
public:
PostConstructor( std::string const& arg ) // implicit conversion!!
: owner( NULL ), arg( arg ) {}
~PostConstructor() { owner->parse(); }
operator std::string() const { return arg; }
};
Base( PostConstructor const& helper )
: name( helper )
{
helper.owner = this;
}
};
class Derived : public Base
{
public:
Derived( PostConstructor const& helper )
: Base( helper )
{
}
};
Это работает, потому что PostConstructor
будет временным, разрушенным
в конце полного выражения (когда Derived
полностью
построен).
В обоих случаях: производные классы должны взаимодействовать (но они не будут
компилировать, если они этого не делают). Трюк также может потерпеть неудачу, если класс
построен в середине более сложного выражения. Что-то
как:
Derived(...).someFunction();
В этом случае конец полного выражения будет после возврата
с someFunction
, что может быть немного поздно для звонка parse()
.
Тем не менее, несмотря на ограничения, я нашел это полезным в некоторых случаях.