如果只知道基类,如何传递派生类?

时间:2014-06-08 17:29:42

标签: c++ class object

我提前道歉,因为我是OO编程的初学者。

我有一个名为Hero的基类,有三个派生类Archer,Warrior和Mage。提示用户选择其中一个,并创建适当的派生类的对象。它们具有不同的初始值和成员函数,下一步是将此对象传递给另一个函数。

让我们说这个函数叫做battle(),它将对象作为参数。我该怎么做呢?我是否必须创建三个单独的battle()或者是否有一种方法来传递对象而无需指定派生类?

void Hero::init(string job)
{  
    if (job == "archer")
        Archer archer;
    else if (job == "mage")
        Mage mage;
    else
        Warrior warrior;

    battle(); // What to put as argument?
}

3 个答案:

答案 0 :(得分:3)

不,您不必创建3个不同的battle函数,避免这正是继承的目的。

您可以创建一个battle功能:

void battle(Hero& hero)
{
}

您可以按如下方式调用它:

battle(archer);
battle(mage);
battle(warrior);

但您需要以其他方式创建自己的英雄,因为现在创建它们时,只要ifelse完成就会超出范围。

答案 1 :(得分:3)

battle()应该将基类的引用或(智能)指针作为参数。例如:

void battle(std::shared_ptr<Hero> ptr);

你的论点也应该是一个聪明的指针:

void Hero::init(const std::string& job)
{
    std::shared_ptr<Hero> ptr;

    if (job == "archer")
        ptr = std::make_shared<Archer>();
    else if (job == "mage")
        ptr = std::make_shared<Mage>();
    else
        ptr = std::make_shared<Warrior>();

    battle(ptr);
}

std::shared_ptr是一个智能指针类,它封装了指针的动态内存分配和资源获取。这样我们就不必在每个地方写new。此外,当智能指针被销毁时(意味着不再存在ptr的副本,如果有的话),则在包含的delete指针上调用Hero

上述方法有效,因为所有三个类都派生自Hero,因此基类可以指向这些派生类指针的地址。

答案 2 :(得分:2)

这是你应该使用运行时多态性的地方 不是创建本地派生类对象实例,而是创建基类指针并将其指向派生类实例:

Hero* hero = new Archer();
Hero* hero = new Mage();
Hero* hero = new Warrior();

然后,您可以将基类指针Hero*传递给方法battle

battle(hero)  

您的方法的签名将是:

void battle(Hero* )  

这意味着,战斗方法可以在运行时接受任何类型的英雄,无论是弓箭手,法师还是战士。