我花了几个小时在网上看,但没有一个像我一样有问题。基本上,我有一个名为MainShop的基类,它有3个派生类,分别是SwordShop,SpellBookShop和BowShop。我希望基类能够从一个派生类调用一个函数,但无论我做什么,它似乎都不起作用! 这是我的代码:
#include "MainShop.h"
//BaseClass cpp
void MainShop::EnterShop(Hero& hero)
{
//Display Choices
switch (choice)
{
//Swords
case 1: SwordShop::soldierShop(hero);//DOES NOT WORK!!
break;
case 2: SpellBookShop::MageShop(hero);//Staffs
break;
case 3: BowShop::ArcherShop(hero);//Bows
break;
default: cout << "Error!, Please try again.";
MainShop::EnterShop(hero);
}
}
我有两个其他的派生类,但它的概念基本相同。我在其中一个派生类中有一个函数,我想从基类中调用它。这是我的派生类:
//SwordShop derived cpp
#include "SwordShop.h"
void SwordShop::soldierShop(Hero& hero)
{
/* some code here*/
}
答案 0 :(得分:3)
由于运行时开销,在超类方法 中选择特定的子类实例(例如dynamic_cast
)并不是一个好的设计,未来的维护等。
您可以将这种switch-case逻辑的负担卸载到由该语言设计的虚函数,以通过基类指针/引用调用特定实例。
例如:
class MainShop
{
public:
virtual void EnterShop(Hero &hero) = 0;
};
class SwordShop: public MainShop
{
void EnterShop(Hero &hero)
{
soldierShop(hero);
}
};
class SpellBookShop: public MainShop
{
void EnterShop(Hero &hero)
{
MageShop(hero);
}
};
int main()
{
...
MainShop *shop = new SwordShop;
// calling soldierShop
shop->EnterShop(hero);
..
shop = new SpellBookShop;
// calling MageShop
shop->EnterShop(hero);
...
}
答案 1 :(得分:1)
如果你需要从任何商店对象(SwordShop等)调用EnterShop,那么覆盖基类中的虚函数就可以了。
class MainShop
{
...
virtual void process_hero(Hero& hero)
{
// add default implementation or set as pure virtual
}
...
};
void MainShop::EnterShop(Hero& hero)
{
process_hero(hero);
}
class SwordShop: public MainShop
{
public:
void process_hero(hero)
{
soldierShop(hero);
}
};
...
但是,在我看来,您希望管理器对象根据“choice”变量调用函数。如果是这种情况,请使用组合而不是继承。
答案 2 :(得分:0)
我猜你可以试试像:
Derived* derived = dynamic_cast<Derived*>(this);
if (derived) {
// this is of Derived type
} else {
// this is of base type but not Derived
}
虽然建议你最好使用虚函数,因为它是正确的用例:
class Base {
public:
virtual void someMethod() = 0;
void anotherMethods() {
someMethod(); // determined by implementation in derived class
}
};
class Derived1 : public Base {
virtual void someMethod() override {
// body
}
};
class Derived2 : public Base {
virtual void someMethod() override {
// body
}
};
更好的可读性,更少出错,更加理智。
答案 3 :(得分:0)
这样的事情怎么样?
显然你必须实现.shop()
函数:
MainShop *ms;
switch(input){
case 1:
ms = new soldierShop(); break;
case 2:
ms = new MageShop(); break
case 3:
ms = new ArcherShop(); break;
}
ms.shop();
答案 4 :(得分:0)
通常使用2个选项来实现所需的功能:
this
指向所需派生类型的指针,并在转换成功时调用你想要的任何内容。