调用派生类方法的基类方法,任何可能的解决方案?

时间:2013-08-07 11:05:25

标签: c++ inheritance

除了修改所有派生类之外,我无法找到问题的解决方案。

我有一个Base类和一些继承自Derived的{​​{1}}个类。现在,还有另一个班级Base,其中包含Container类指针Base的向量。

上面的列表在创建后填充了所有派生类对象的地址。

所有文件都在不同的翻译单元中。

我想做什么

std::vector<Base *> derivList能够使用Container中指向不同派生类的vector元素从1)类调用Base类的单个函数。

Container但是当我调用这个函数时,在该函数中我应该能够访问2)类指针所在的public members类的Derived指着。

Base

我的约束是

  • 我不应该触摸 class Base { public: virtual void someMethod(); void containerCallsThisMethod(); }; void Base::containerCallsThisMethod() { // I need to access the public functions of derived classes here // say: Derived1::calc(), Derived2::calc,.( I don't have derived class names here in Base) } class Derived1:public Base { public: void calc(); }; class Container { std::vector<Base *> derivList; void execute(); }; void Container::execute() { for(i = 0; i < derivList.size();i++) { derivList[i]->containerCallsThisMethod(); } } 课,因为它非常费力,但我仍然可以更改Derived课程。
  • Base不能拥有Base类的列表(甚至不是前向声明)。

我认为我可以通过Derived指针执行此操作,因为它具有this函数的ClassName类型,并且它指向派生类对象。但我无法使用non-const调用Derived类方法。

有没有办法在没有太多劳动力,任何具体设计模式或黑客的情况下做到这一点?

3 个答案:

答案 0 :(得分:0)

如果您有一个带派生类的基类,这些派生类会覆盖该函数,让我们调用它func(),然后调用func()的覆盖。就我所知,你想要的唯一解决方案是继承派生类的良好行为或将func()作为静态函数,将其放入友元类,或者将其放入静态内部类中

答案 1 :(得分:0)

如果我理解正确,您可以在calc中将protected声明为(可能是Base)虚拟函数。仅当calc在所有派生类中具有完全相同的签名时,此方法才有效。在这种情况下,不必在派生类中更改代码。现在,当您在this->calc中致电Base时,它将被发送到Derived中的实施。

class Base
{
  public: 
    vitrual void someMethod();
    void containerCallsThisMethod();

    virtual ~Base(); // Important !!
  protected:
    virtual void calc() = 0;
};
void Base::containerCallsThisMethod()
{
  calc(); // will call derived class implementation
}

请记住在执行此操作时向Base添加虚拟析构函数。

这是有效的,因为当一个方法声明为虚拟时,它也将在所有派生类中都是虚拟的,即使没有明确指定。

答案 2 :(得分:0)

如果

  

不同派生类的公共成员

您需要访问具有相同签名的方法,但在每个派生类中实现的方式不同(这是您的示例所示),您只是发现自己处于最基本的用例虚拟方法绑定。

然后你会非常幸运:你只需要在 Base 类定义中的方法签名之前添加virtual关键字。

class Base
{
    void containerCallsThisMethod()
    {
         calcDerivedMethod();
    }

    virtual void calcDerivedMethod();
}

class DerivedA : public Base
{
    void calcDerivedMethod()
    {
       //Specific implementation for DerivedA class.
    }
}

这里发生的正是您所描述的要求:    容器方法执行()在它指向的每个对象上依次调用 containerCallsThisMethod()。此调用最终始终为 Base :: containerCallsThisMethod()。但是在最后一个方法中,对 calcDerivedMethod()的调用被分派到指针的动态类型(即Derived类)。只需在基础中的 calcDerivedMethod()声明前添加虚拟关键字,即可获得此动态调度。