作为函数传递后C++从父项转换为子项

C++ Casting From Parent to Child After Passing as a Function?

本文关键字:转换 函数 C++      更新时间:2023-10-16

当涉及到从C++中的接口继承时,我想知道这(上面的标题)是否完全可能。

class Animal
{
public:
virtual void Eat(Animal& a) = 0; //Function that attempts to eat an animal.
}
class Dog : Animal
{
public:
void Eat(Animal& a);
}
void Dog::Eat(Animal& a)
{
Dog d = (Dog) a;
// Do something.
}
int main()
{
Dog dog1 = Dog();
Dog dog2 = Dog();
dog1.Eat(dog2);
return;
}

所以基本上,我知道我的狗要吃的动物只是其他狗(在所有情况下都是,而不仅仅是在这个特定的例子中)。然而,我继承了一个纯虚拟类Animal,它要求我用Animal参数定义函数。

我知道有一个参数作为Animal会导致函数Dog::Eat认为这个参数是Animal而不是Dog。然而,考虑到要表示为狗的对象的数据仍然在那里我非常确定有一种方法可以将动物建立(铸造等)为狗,我只是不知道如何,也不太确定如何搜索。

所以我想知道我该怎么做。我很确定您可以使用动态强制转换或重新解释强制转换,但我的印象是,如果可以的话,您通常希望尽量减少这些强制转换的使用。我对C++中的面向对象很陌生,因为我过去主要只使用C.

您确实可以强制转换它(假设您打算从Animal公开派生Dog);但是您必须强制转换引用或指针。您对某个值的强制转换将尝试从传入的Animal创建一个新的Dog;并且没有合适的转换。

// safest, if you can't guarantee the type
Dog & d = dynamic_cast<Dog&>(a);  // throws if wrong type
Dog * d = dynamic_cast<Dog*>(&a); // gives null if wrong type
// fastest, if you can guarantee the type
Dog & d = static_cast<Dog&>(a);   // goes horribly wrong if wrong type

不要使用reinterpret_cast;这允许各种疯狂的转换,所以很容易出错。也不要使用C风格的强制转换(Dog&)a,它允许比reinterpret_cast更多的转换,并且语法微妙且难以搜索。

一般来说,您根本不应该需要强制转换——尝试设计基类,使其公开您想用它做的一切,而不需要知道实际的对象类型。