如何从基类中的派生类调用函数?

时间:2013-12-24 02:16:56

标签: c++ class oop object inheritance

我花了几个小时在网上看,但没有一个像我一样有问题。基本上,我有一个名为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*/
}

5 个答案:

答案 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”变量调用函数。如果是这种情况,请使用组合而不是继承。

Prefer composition over inheritance?

答案 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个选项来实现所需的功能:

  1. 使用dynamic_cast&lt;&gt;提升this指向所需派生类型的指针,并在转换成功时调用你想要的任何内容。
  2. 使用模板化基类和奇怪的重复模板模式 - 基本上,将所需的派生类型作为模板参数传递给基类(http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern)。