В следующем коде я могу назначить возврат D::clone()
на указатель на B
, но не указатель на D
, Можно ли вернуть фактический полиморфный тип из вызова базового указателя?
struct B
{
virtual B * clone() { return this; }
};
struct D : B
{
D * clone()
{
std::cout << std::is_same<decltype(this), D *>::value << std::endl;
return this;
}
};
int main()
{
B * b = new D();
B * bb = b->clone(); // prints "1"std::cout << std::is_same<decltype(b->clone()), D *>::value << std::endl; // prints "0"D * d = b->clone(); // error: invalid conversion from B * to D * (GCC 5.1)
}
Номер вызова clone()
на базе B
класс D
вернет D*
бросить в B*
,
Вы можете изменить это, выполнив static_cast<D*>
если вы абсолютно уверены, или dynamic_cast<D*>
если вы не уверены Если вы уверены, что вы должны сделать переменную b
быть D*
,
В C ++ вы должны кодировать то, что вы знаете о состоянии программы во время компиляции, независимо от ситуации времени выполнения, как типы. Храня D*
в B* b
вы говорите компилятору не «знать», что данные, на которые указывают D
«. Вместо этого вы говорите» код с помощью B*b
должен быть действительным для любого указателя наB
, очевидно D* d = b->clone();
не гарантируется быть действительным для каждого указателя наB
,