Короткий ответ: вы не можете.
Рассмотрим такую функцию
// definition of struct A
void func(A *p)
{
delete p;
}
и вызывающий объект в другом модуле компиляции
// definitions of struct A and B as in question
void func(A *);
void caller()
{
func(new B);
}
In В этом случае код в func()
вообще не имеет видимости типа B
, не говоря уже о потенциале того, что указатель p
, который он получает, фактически указывает на B
. Поскольку func()
делает delete p
, функция caller()
вызвала неопределенное поведение func()
.
Реальное решение в этом случае состоит в том, что B
не должен наследовать от A
. Уже есть явный намек на это в том факте, что A
не имеет деструктора virtual
. Это предотвратит caller()
вызов func()
с B *
.
Если вы хотите, чтобы B
предоставлял тот же интерфейс, что и A
, тогда вам нужно использовать композицию и определить все функции-члены из B
, поэтому они пересылаются в содержащийся A
. Например;
struct B
{
B() : a() {};
void some_member(some_type arg)
{
a.some_member(arg); // assume A has this member that accepts these arguments
}
private:
A a;
};
Очевидно, что доступны варианты, если struct A
можно изменить, но в вопросе явно указан вариант использования, когда это невозможно.