Преобразование указатель-указатель между производными и базовыми классами?
Относительно следующей программы на C++:
class Base { };
class Child : public Base { };
int main()
{
// Normal: using child as base is allowed
Child *c = new Child();
Base *b = c;
// Double pointers: apparently can't use Child** as Base**
Child **cc = &c;
Base **bb = cc;
return 0;
}
GCC выдает следующую ошибку в последнем операторе присваивания:
error: invalid conversion from ‘Child**’ to ‘Base**’
Мой вопрос состоит из двух частей:
- Почему нет неявного преобразования из Child** в Base**?
- Я могу заставить этот пример работать с броском в стиле C или
reinterpret_cast
, Использование этих слепков означает отказ от всех типов безопасности. Могу ли я что-нибудь добавить к определениям классов, чтобы эти указатели приводились неявно, или, по крайней мере, сформулировать преобразование так, чтобы я мог использоватьstatic_cast
вместо?
1 ответ
Решение
Если бы это было разрешено, вы могли бы написать это:
*bb = new Base;
А также c
в конечном итоге будет указывать на экземпляр Base
, Плохой.
Указатели - это виртуальные адреса. Обычно вы несете ответственность за то, что с ним делаете. Используя msvc 2019. Я могу привести один к base, но не два:
example 1:
int p;
int *p1 = &p;
int **p2 = &p1; //OK
example 2:
struct xx {};
struct yy : public xx {};
yy p;
yy *p1 = &p;
xx **p2 = &p1; //Just a strange error
example 3:
struct xx {};
struct yy : public xx {};
yy p;
xx *p1 = &p;
xx **p2 = &p1; //OK