C++ 具有继承层次结构的动态强制转换

C++ 具有继承层次结构的动态强制转换,c++,casting,C++,Casting,所以我有这个代码: Base*objbase=new-Derived(); //在运行时使用dynamic_cast执行向下广播 派生*objDer=动态转换(objBase); if(objDer)//检查强制转换是否成功 objDer->CallDerivedFunction(); 这是我书中cast操作符部分的一段代码 现在我为什么要这样做,我不明白为什么必须动态地将指针投射到指向派生对象的基础对象;对我来说,这与多态性有关,多态性使我们能够执行objBase->DeriveClassF

所以我有这个代码:

Base*objbase=new-Derived();
//在运行时使用dynamic_cast执行向下广播
派生*objDer=动态转换(objBase);
if(objDer)//检查强制转换是否成功
objDer->CallDerivedFunction();
这是我书中cast操作符部分的一段代码

现在我为什么要这样做,我不明白为什么必须动态地将指针投射到指向派生对象的基础对象;对我来说,这与多态性有关,多态性使我们能够执行
objBase->DeriveClassFunction()
,但我真的不知道

首先,它为什么这样做:
Base*objbase=new-Derived(),然后为什么它再次将基对象指针强制转换为派生对象,我不太明白为什么


提前感谢。

这段代码只是一个可能的演示。它描述了一个工具,你如何使用这个工具取决于你自己。一个稍大的例子可能是:

class Animal {
    void Feed();
};
class Cat : public Animal { /*...*/ };
class Dog : public Animal {
    // Only dogs need to go out for a walk
    void WalkTheDog();
};

void Noon(Animal* pet)
{
    // No matter what our pet is, we should feed it
    pet->Feed();

    // If our pet is a dog, we should also take it out at noon
    Dog* dog = dynamic_cast<Dog*>(pet);
    if(dog) // Check if the cast succeeded
        dog->WalkTheDog();
}

Noon(new Cat()); // Feed the cat
Noon(new Dog()); // Feed the dog and take him out
类动物{
空进料();
};
猫类:公共动物{/*…*/};
犬类:公共动物{
//只有狗需要出去散步
void WalkTheDog();
};
中午(动物*宠物)
{
//不管我们的宠物是什么,我们都应该喂它
pet->Feed();
//如果我们的宠物是狗,我们也应该在中午把它带出去
狗*狗=动态施法(宠物);
if(dog)//检查施法是否成功
狗->步行狗();
}
中午(新猫());//喂猫
中午(新狗());//喂狗,然后把它带出去

请注意,每个动物都有Feed()函数,但只有狗有WalkTheDog()函数,因此为了调用该函数,我们需要有一个指向狗的指针。但是为这两种类型复制Noon()函数也是一种浪费,特别是如果我们以后可能添加更多的动物。因此,Noon()函数适用于任何类型的动物,并且仅当动物实际上是狗时才执行特定于狗的操作。

该代码片段只是一个可能的演示。它描述了一个工具,你如何使用这个工具取决于你自己。一个稍大的例子可能是:

class Animal {
    void Feed();
};
class Cat : public Animal { /*...*/ };
class Dog : public Animal {
    // Only dogs need to go out for a walk
    void WalkTheDog();
};

void Noon(Animal* pet)
{
    // No matter what our pet is, we should feed it
    pet->Feed();

    // If our pet is a dog, we should also take it out at noon
    Dog* dog = dynamic_cast<Dog*>(pet);
    if(dog) // Check if the cast succeeded
        dog->WalkTheDog();
}

Noon(new Cat()); // Feed the cat
Noon(new Dog()); // Feed the dog and take him out
类动物{
空进料();
};
猫类:公共动物{/*…*/};
犬类:公共动物{
//只有狗需要出去散步
void WalkTheDog();
};
中午(动物*宠物)
{
//不管我们的宠物是什么,我们都应该喂它
pet->Feed();
//如果我们的宠物是狗,我们也应该在中午把它带出去
狗*狗=动态施法(宠物);
if(dog)//检查施法是否成功
狗->步行狗();
}
中午(新猫());//喂猫
中午(新狗());//喂狗,然后把它带出去

请注意,每个动物都有Feed()函数,但只有狗有WalkTheDog()函数,因此为了调用该函数,我们需要有一个指向狗的指针。但是为这两种类型复制Noon()函数也是一种浪费,特别是如果我们以后可能添加更多的动物。因此,Noon()函数适用于任何类型的动物,并且仅当动物实际上是狗时才执行特定于狗的操作。

因此,本质上它只允许在运行时执行类型检查,而不允许执行其他操作?是的,它在运行时执行类型检查。它允许您从基指针访问派生类的函数/成员。例如,pet->WalkTheDog()实际上会导致编译时错误,因为animal类根本没有这样的函数。(但如果需要,您也可以仅将其用于类型检查目的)因此,本质上它只允许在运行时进行类型检查,而不允许其他任何操作?是的,它在运行时进行类型检查。它允许您从基指针访问派生类的函数/成员。例如,pet->WalkTheDog()实际上会导致编译时错误,因为animal类根本没有这样的函数。(但如果需要,您也可以仅将其用于类型检查目的)注意:继承最好与通用的
virtual
函数一起使用,以便对象的用户不需要知道对象的类型<代码>动态_cast
ing无法很好地缩放。最终,您会发现自己需要进行更多的检查,以确保拥有正确的对象,而不是实际解决手头问题的代码。请参阅,以获取帮助您检测何时遵循此错误路径的工具。注意:继承最好与通用的
virtual
函数一起使用,以便对象的用户不需要知道对象的类型<代码>动态_casting无法很好地缩放。最终,您会发现自己需要进行更多的检查,以确保拥有正确的对象,而不是实际解决手头问题的代码。请参阅,以获取帮助您检测何时遵循此错误路径的工具。