C ++派生类 - 从父类调用虚函数?

时间:2015-12-22 00:59:44

标签: c++ oop inheritance

我在使用C ++编写大型包时相对较新,因此我并不完全熟悉该语言中的一些OOP技术。

我正在开发一个代码,可以运行模拟来计算各种模型框架内材料的变形。我有一个总体Sim课程,其中包含set_boundary_conditions()update_grid()solve()等方法。

我想将各种模型实现为派生类。例如,如果您只想考虑线性弹性方程,ElasticSim可塑性等等,我会得到一个Sim类,它来自PlasticSim

因为模型定义了必须求解的方程式,它进入了update_grid()函数,所以我已经update_grid() virtual,因此可以针对每个模型实现不同的方法。此外,set_boundary_conditions()更具体 - 给定模型中的不同模拟将具有不同的边界条件,因此在virtual和任何派生类中都应该Sim。将会有另一个派生类,它实现给定物理情况的边界条件。

这可能过于复杂,但我认为这是一种非常模块化和通用的方法来解决这个问题。但我离题了。我有一个重要问题。

首先,solve()方法对于每个模型都是相同的。因此,我想在Sim中定义它。但是,它调用virtual函数,稍后将由派生类实现。也就是说,在伪代码和c ++的混合中:

Sim::set_boundary_conditions()
for every time step...
    Sim::update_grid()

在我能够正确测试之前会有相当多的编码,我无法在线找到合适的答案。这真的有意义吗?特别是,我正在调用Sim::update_grid()Sim::set_boundary_conditions(),尽管这些函数实际上将分别在派生类和派生类的派生类中实现。

1 个答案:

答案 0 :(得分:2)

  

这实际上有意义吗?

是的,Sim::solve非虚拟和调用虚拟功能完全没问题。只有你必须注意虚拟调用的情况才在构造函数和析构函数中(因为vtable可能尚未完全形成或者可能已被破坏)。

在某些时候可能对您有用的习惯用语是NVI(非虚拟接口)。该想法包括对公共接口使用非虚方法,对受保护/私有方法使用虚方法。这个想法是允许集中控制,但仍然允许某些部分的可覆盖性。例如:

class Foo
{
public:
    virtual ~Foo() {}

    // public non-virtual interface: calls virtual interface.
    void do_something()
    {
        // Can add central stuff here that affects the 
        // entire hierarchy at any given time.
        do_something_impl();
    }

private:
    // subclasses can override this part.
    virtual void do_something_impl() = 0;
};

这种设计留下了摆动空间来做一些集中适用于整个层次结构的事情(在远见或后见之明),同时允许子类部分覆盖行为并导致新的代码子分支。

然而,你在基类中调用虚拟方法定义的这个中心sim方法有什么用。这将使它成为混合具体实现和可覆盖接口的抽象基类,而不是没有任何具体实现的纯虚拟接口,例如,同样,值得注意的是,您可以为虚函数提供默认实现 - 并非基类中的所有方法都不需要是纯虚函数,甚至根本不需要虚函数。