C++ 如何从基类中的派生类调用函数?
我花了好几个小时上网,但没有一个像我一样有同样的问题。基本上,我有一个名为MainShop的基类,它有3个派生类,分别是剑店、咒语书店和弓箭店。我希望基类能够从一个派生类调用函数,但无论我做什么,它似乎都不起作用! 这是我的密码:C++ 如何从基类中的派生类调用函数?,c++,class,oop,object,inheritance,C++,Class,Oop,Object,Inheritance,我花了好几个小时上网,但没有一个像我一样有同样的问题。基本上,我有一个名为MainShop的基类,它有3个派生类,分别是剑店、咒语书店和弓箭店。我希望基类能够从一个派生类调用函数,但无论我做什么,它似乎都不起作用! 这是我的密码: #include "MainShop.h" //BaseClass cpp void MainShop::EnterShop(Hero& hero) { //Display Choices switch (choice)
#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);
}
}
我想你可以试试这样的东西:
Derived* derived = dynamic_cast<Derived*>(this);
if (derived) {
// this is of Derived type
} else {
// this is of base type but not Derived
}
更好的可读性,更少出错,更理智。我想你可以尝试以下方法:
Derived* derived = dynamic_cast<Derived*>(this);
if (derived) {
// this is of Derived type
} else {
// this is of base type but not Derived
}
更好的可读性,更少出错,更理智。像这样的东西怎么样? 显然,您必须实现
.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();
像这样的怎么样? 显然,您必须实现
.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();
通常有两个选项用于实现所需的功能:
这个
指针提升到所需的派生类型,并在cast成功时调用所需的任何函数通常有两个选项用于实现所需的功能:
这个
指针提升到所需的派生类型,并在cast成功时调用所需的任何函数动态\u 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);
...
}
由于运行时开销和将来的维护等原因,在超类方法中选择特定的子类实例(例如通过动态\u 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);
...
}
如果您需要从任何shop对象(Swarshop等)调用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”变量调用函数。如果是这种情况,请使用组合而不是继承
如果您需要从任何shop对象(Swarshop等)调用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”变量调用函数。如果是这种情况,请使用组合而不是继承
这就是虚拟函数的用途。是的,拿着一个指向基类的指针,只需调用
.shop()
我认为,您似乎采用结构化的OO方法来构建虚拟函数是很好的,只要您觉得您正在学习或朝着一个目标前进,您肯定应该继续沿着这条道路前进。然而,从长远来看,我的经验是继承和多态性会导致程序不灵活和逻辑重复,尤其是当项目变得更大时。我有过更紧凑、更灵活的程序,具有类型特征和组合。诚然,进入的门槛更高,所以我说现在继续走这条路不是个坏主意。这就是虚拟函数的用途。是的,拿一个指向基类的指针,只需调用.shop()
我认为,您似乎采用结构化的OO方法进行构建,这是一件好事,只要您觉得自己正在学习或朝着一个目标前进,您肯定应该继续走这条路。然而,从长远来看,我的经验是继承和多态性会导致程序不灵活和逻辑重复,尤其是当项目变得更大时。我有过更紧凑、更灵活的程序,具有类型特征和组合。诚然,进入的门槛更高,所以我说现在继续走这条路不是个坏主意。或者虚拟功能?不是虚拟函数无法控制调用哪个派生实例。在很多情况下,你需要调用一些特定的东西(OP可能一直在问这个问题)。99%的人肯定OP需要这样做,这是因为糟糕的设计。OP需要一个虚拟函数,如果不是,则需要重构。如果你不同意我的观点,我强烈建议你解释一下你的解决方案是好的做法,否则答案很可能会误导你?如果我选择了2,我将不得不改变整个项目,而且我并不是真正的C++经验者,所以我要花很长时间才能掌握它。然而,选项1看起来很有趣。你能给我一个如何使用选项1的例子吗?我同意这不是OP问题的解决方案,但我决定放弃-1,因为从技术上讲,这些是“在基类内调用派生类的函数”或虚拟函数的方法。不可以虚拟函数无法控制调用哪个派生实例。在很多情况下,你需要调用一些特定的东西(OP可能一直在问这个问题)。99%的人肯定OP需要这样做,这是因为糟糕的设计。OP需要一个虚拟函数,如果不是,则需要重构。如果你不同意我的观点,我强烈建议你解释一下你的解决方案是好的做法,否则答案很可能会误导你?如果我选择了2,我将不得不改变整个项目,而且我并不是真正的C++经验者,所以我要花很长时间才能掌握它。选择