为什么C ++允许将指向基础对象的指针转换为派生类的指针

时间:2012-11-21 03:43:10

标签: c++ pointers inheritance

  

可能重复:
  Downcasting using the Static_cast in C++

我很困惑,何时需要将指向基础对象的指针转换为派生类的指针? 任何人都可以帮我一个例子吗?

4 个答案:

答案 0 :(得分:1)

您在谈论什么样的转换?

如果它是关于向下投射(或动态投射,这是同一种类,但它在运行时验证),那么你可以这样做来强制类型检查器不要通过强制执行您指定的类型来检查该特定类型。

这意味着它可能会破坏您的代码,在特定指令中缺少保证的类型安全性,但有时需要它,即使好的设计永远不需要先验。

必要性是这样的事实:没有强制转换,即使你确定指向基类的指针包含派生类(但编译器可以'),也不允许调用派生类的任何方法。 t验证它。)

答案 1 :(得分:1)

:当

所以这是一个例子:

说你有一个工厂(一个动物工厂),你可以发一个字符串或一个你想要什么类型的对象的枚举...

“嘿动物工厂,给我'狗'”

有两种方法可以写你的工厂......

你可以为每一种动物编写一个函数(好的程序员不这样做):

  • Dog * GetDog();
  • Cat * GetCat();

或者你可以写一个像这样的函数的工厂(暂不考虑泛型):

  • Animal * GetAnimal(string animalType);

你知道Animal实际上是一只狗或猫,所以你可以将它强制转换为你需要的东西 WHEN 你需要访问Dog或Cat的成员......

我在C ++中最喜欢做的事情是进入某事物的临时演员 (原谅我的C ++生锈了)

Animal* myAnimal = Factory.GetAnimal("Dog");
int barkVolume = ((Dog*)myAnimal).BarkVolume;

答案 2 :(得分:1)

想象一下,您有一个基类Animal和两个派生类CatDog

// Assume methods are public.
class Animal { virtual void Attack(); }
class Dog : public Animal { void Meow(); }
class Cat : public Animal { void Bark(); }

我们可以使用基类指针来引用我们的派生对象。这有助于我们现在可以将它们包含在同一类型中。

Animal* myCat = new Cat;
Animal* myDog = newDog;
std::vector<Animal*> myAnimals;
myAnimals.push_back(myCat);
myAnimals.push_back(myDog);

这很有用,因为我们可以将所有种类的动物称为基本成员函数,而不管它们的派生类类型。

// Call Attack() on every cat and dog.
for_each(myAnimals.begin(), myAnimals.end(), [](auto& e) { e->Attack(); });

您可以使用动态强制转换来测试其中一个基本指针是否可以转换为派生类指针。

Cat* realCat = dynamic_cast<Cat*> myAnimals[0]; // Success. Pointer is valid.
Cat* fakeCat = dynamic_cast<Cat*> myAnimals[1]; // Failure, it's not a cat. NULL.

现在可以从派生类指针调用成员方法,例如Meow()。之前这是不可能的,因为Animal没有这些方法。

realCat->Meow(); // Valid.
myCat->Meow(); // Animal*, there is not Meow() method.

答案 3 :(得分:0)

您需要这样做才能访问基类中不存在的派生类的成员。但是,通过良好的编程实践和泛型,您可能不应该将指针键入为基类。