何时需要指向派生类对象的基类指针 C++

When do you need a base class pointer to a derived class object in C++?

本文关键字:基类 指针 C++ 对象 派生 何时需      更新时间:2023-10-16

我知道运行时多态性在面向对象编程语言中的用途是什么。例如,基类Superhero对于定义可以在不同的超级英雄中继承和扩展的Superhero的基本抽象属性很有用,例如Batman

我也知道,当存在is-a关系时,例如,Superman is-a超级英雄,我们使用基类指针指向派生类对象,例如......

Superhero *h = new Spiderman();

有效。

但我想知道在什么情况下我们需要做这样的事情,为什么我们不能只使用......

Spiderman *s_man = new Spiderman()

什么情况或情况会迫使我们使用基类指针来保存子类对象。

如果有人能向我说清楚这一点,我将不胜感激。

通过基类指向派生类,您可以对基类对象组执行操作,就好像它们都相同一样。在这个人为但符合奇迹的电影宇宙的例子中,您可以将所有复仇者收集在一个列表中并执行某种操作。

std::vector<Superhero*> GetAvengers()
{
    std::vector<Superhero*> avengers;
    avengers.push_back(new Spiderman());
    avengers.push_back(new CaptainAmerica());
    avengers.push_back(new IronMan());
    avengers.push_back(new Thor());
    // ... ad nauseam for three generations of unnecessary standalone films
    return avengers;
}
void FightThanos()
{
    SuperVillan* thanos = new Thanos();
    auto Avengers = GetAvengers();
    for(auto&& avenger : Avengers)
    {
        avenger->SaySomethingSnarky();
        avenger->ParticipateInMontageActionSequence(thanos);
    }
    // Clean up after the avengers, they're not needed for another 4 years
    for(auto&& avenger : Avengers)
    {
       delete avenger;
    }
    avengers.clear();
 } 

如果你想对所有类型的超级英雄进行标准调用。但实现是不同的。这里没有语法检查:)

class Superhero
{
public:
virtual void changeClothes() = 0;
}
class Spiderman : public Superhero
{
public:
void changeClothes()
{
  body.wear(spideySuit);
}
};

class Hulk public Superhero
{
public:
void changeClothes()
{
  body.shorts.TearApart();
}
};
SuperHero * spidy = (Superhero *)  new Spiderman;
SuperHero * hulkster = (Superhero *)  new Hulk;
spidey->changeClothes();
hulkster->changeClothes();

考虑一个超级英雄指针列表。 这样的列表可以存储对new Spiderman()new Superman()和其他继承超级英雄的对象的引用(指针)。

@lcs很好地说明了这一概念。