在下面的代码中,我可以将 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
A类D
将返回D*
转换到 B*
.
您可以通过执行 static_cast<D*>
来扭转这种情况如果您绝对确定,或者 dynamic_cast<D*>
如果你不确定。如果您确定,那么您应该真正将变量设置为 b
是 D*
.
在 C++ 中,无论运行时情况如何,您都应该在编译时将您所了解的程序状态编码为类型。通过存储D*
进入B* b
,您告诉编译器不“知道”所指向的数据“是 D
”。相反,您是说“使用 B*b
的代码应该对任何指向 B
的指针有效。显然 D* d = b->clone();
不能保证对每个指向 B
的指针有效。
关于使用带有虚函数的协变返回类型的 C++ 无效转换错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31414735/