如何从基类中的派生类调用函数
How to call a function from a derived class in a base class?
我花了几个小时在网上寻找,但没有一个人遇到和我一样的问题。基本上,我有一个名为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*/
}
在超类方法中选择特定的子类实例不是一个好的设计
,例如,由于运行时开销和未来的维护等,通过dynamic_cast
。
您可以将这种开关案例逻辑的负担卸载到虚函数上,这些函数由语言设计,通过基类指针/引用调用特定实例。
例如:
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);
...
}
我想
你可以尝试这样的事情:
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
}
};
更好的可读性,更少的错误,更理智。
如果您需要从任何商店对象(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);
}
};
...
但是,在我看来,您希望管理器对象根据"选择"变量调用函数。如果是这种情况,请使用组合而不是继承。
更喜欢组合而不是继承?
这样的事情怎么样?显然,您必须实现.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();
通常有 2 个选项可用于实现所需的功能:
- 使用 dynamic_cast<> 将指针提升
this
指向所需的派生类型,并在强制转换成功时调用所需的任何内容。 - 将模板化基类与奇怪的重复出现的模板模式结合使用 - 基本上,将所需的派生类型作为模板参数传递给基类 (http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern)。
相关文章:
- 为什么使用 "this" 指针调用派生成员函数?
- 绑定派生类方法C++从实例范围之外的分隔 std::function 变量调用
- 使用 std::variant<...时调用 BaseState 函数而不是派生函数>
- QWidget::p aintEngine:不应再在 QTreeWidget 派生类中调用
- 调用从模板派生的类的静态方法,而不指定模板
- 调用派生类成员函数
- 从基类实例调用派生类方法而不进行强制转换
- 派生类调用父类的方法,该方法调用重写的虚拟方法调用错误的方法
- 从 c++ 中派生类的析构函数调用虚函数
- 从基类 (C++) 调用派生类中的非虚函数
- 调用不在基类中的派生类函数而不进行动态强制转换,以最大程度地提高性能
- 在将派生类指针类型转换为派生类指针后,从基类指针调用派生类函数
- 如何从 Gtk::窗口调用派生对象的析构函数
- 在dynamic_pointer_cast后调用派生类的构造函数
- 如何使派生类函数在调用时始终调用相同的基类函数?
- C++初始化之前派生类调用基类的方法
- 为什么派生类的实例从基类调用方法?
- 从 Base 引用对象调用派生类的成员
- 使用回调函数从构造函数调用虚拟/派生方法的替代方法?
- 基函数中的公共函数,当使用派生对象通过另一个基函数调用时,派生调用基函数