Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如果只知道基类,如何传递派生类?_C++_Class_Object - Fatal编程技术网

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

C++ 如果只知道基类,如何传递派生类?,c++,class,object,C++,Class,Object,我提前道歉,因为我是OO编程的初学者 我有一个叫做英雄的基本职业,有三个派生职业:弓箭手、战士和法师。系统将提示用户选择其中一个,并创建相应派生类的对象。它们具有不同的初始值和成员函数,下一步是将此对象传递给另一个函数 假设函数名为battle(),它将对象作为参数。我该怎么做呢?我是否必须创建三个单独的battle(),或者是否有一种方法可以在不指定派生类的情况下传递对象 void Hero::init(string job) { if (job == "archer")

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

我有一个叫做英雄的基本职业,有三个派生职业:弓箭手、战士和法师。系统将提示用户选择其中一个,并创建相应派生类的对象。它们具有不同的初始值和成员函数,下一步是将此对象传递给另一个函数

假设函数名为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个不同的
battle
函数,避免这正是继承的目的

您可以创建单个
battle
功能:

void battle(Hero& hero)
{
}
你可以这样称呼它:

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

但是您需要以另一种方式创建Hero,因为现在创建Hero时,一旦
if
else
完成,它们就不在范围之内。

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

Hero* hero = new Archer();
Hero* hero = new Mage();
Hero* hero = new Warrior();
然后可以将基类指针
Hero*
传递给方法
battle

battle(hero)  
您的方法的签名为:

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

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

void战(std::shared_ptr ptr);
你的论点也应该是一个聪明的指针:

void Hero::init(const std::string和job)
{
std::共享的ptr;
如果(作业==“弓箭手”)
ptr=std::使_共享();
否则如果(作业==“法师”)
ptr=std::使_共享();
其他的
ptr=std::使_共享();
战斗(ptr);
}
std::shared_ptr
是一个智能指针类,它封装了指针的动态内存分配和资源获取。这样我们就不必到处写
new
。此外,当智能指针被销毁时(意味着不再存在
ptr
的副本,如果有),则对包含的
Hero
指针调用
delete


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

谢谢,但是
Hero&
是什么意思?我不熟悉这个概念。那是一个参考资料。这意味着您使用的是在battle函数之外创建的对象。这仍然会创建派生类对象实例。请重新表述这句话。@cppcoder我有点困惑。您可以声明指向动态分配对象的指针。当指针和对象属于不同的类时,这是如何工作的?这是运行时多态性的基础。在你的例子中,
Archer
是一个
英雄
Mage
是一个
英雄
战士
是一个
英雄
。通过继承,您在类之间建立了一种
is-a
关系。std::shared_ptr和std::make_shared似乎不会编译。我使用的是最新版本的代码块。@geft您需要#包含文件。