具体类中的C ++强制方法覆盖

时间:2011-11-04 15:47:44

标签: c++ abstract-class

在C ++中是否有一种方法可以编写一个具体的类,当另一个类派生它时,它有一个必须覆盖的方法。抽象类允许强制派生类创建任何抽象方法的具体版本,但我想要的是一个强制执行此操作的基类,但也可以单独使用它。我知道抽象方法也可以指定默认功能,但这仍然是一个无法实例化的抽象类。

我也查看了模板方法模式,但这似乎也不是我想要的。

6 个答案:

答案 0 :(得分:3)

我将假设您正在寻找编译时强制执行此条件(感谢@Chad将其指出)

我所知道的C ++中没有直接的语言机制。我的意思是,没有一个保留关键字可以放在你的方法声明之前,以达到你想要的目标。

我认为您所说的是指向软件中的设计问题。假设您要强制foo()方法由以下代码段中的所有继承类重新实现

class BaseButConcrete
{
    ... //Common stuff
    ... //

    virtual void foo()
    { /*implementation that you do not want to be inherited, but will be...*/ }
}

class DerivedOtherConcrete : public BaseButConcrete
{
    void foo()
    { /*different implementation, 
      but no obligation from compiler point of view*/ }
}

我看不出为什么所有常见的东西都不能在抽象基类中移动的好设计理由。 根据您的描述,您不希望继承Derived中的 foo 实现,因此不要继承该部分!因此,非常经典的设计应该做到这一点:

class AbstractBase
{
    ... //Common stuff has moved here
    ... //
    virtual void foo() =0;
}

class NotAnymoreBaseButStillConcrete : public AbstractBase
{
    void foo()
    { /*implementation that should not be inherited,
      and that will not by design*/ }
}

class DerivedOtherConcrete : public AbstractBase
{
    void foo()
    { /*different implementation, 
      now mandatory compiler-wise for the class to be concrete*/ }
}

这样,常见的东西仍然在所有派生类之间共享,并且你保留你不想继承的内容(即 foo 实现),这些内容在不在同一继承路径上的类中分开

答案 1 :(得分:1)

一种选择是将类的所有实现放入一个抽象的超类中,并从中继承。

  • 将具体类T的所有实现移动到抽象类S中。
  • 在S中,使必须被覆盖的方法成为纯虚函数 - 并提供它的定义。
  • T子类S。
  • 在T中,覆盖必须被覆盖的函数,并调用S实现。
  • 而不是继承T,子类S。
  • 防止T。
  • 的子类化

答案 2 :(得分:1)

正如其他人所提到的,你可以通过将当前的具体类拆分为抽象类和具体类来“修复”这一级别的派生。

该方法的一个非常罕见的概括是拥有一个必须用于从每个抽象类中创建具体类的类模板。例如,它可以提供clone方法。或者,在Microsoft的ATL中,它提供IUnknown接口实现。

然而,具有自动生成的具体叶子的抽象类层次结构通常是太多的工作和复杂化。实际的方法是仅记录必须覆盖的内容,例如clone。你通常不能强迫其他人的代码是正确的,你只能在那个方向上帮助它。

顺便说一句,如果你对你的特定问题更加具体,那么可能会有比这个普遍的希望更好的答案。

然而,通过概括你的问题,你概括了答案。

干杯&第h。,

答案 3 :(得分:1)

我在基类中使用了一个断言宏,以确保在开发人员测试期间该函数在运行时失败。

as.character(time_to_expiry)

答案 4 :(得分:0)

不,这是不可能的。如果要强制(在编译时)派生类来定义虚函数,那么它的基类需要是抽象的,或者换句话说,基类需要具有纯虚函数。抽象类(具有纯虚函数)不能具体,即你无法实例化它。

答案 5 :(得分:0)

我没有定义中间类,而是在多重继承上找到了更直观,更干净的杠杆。如果我们的派生类也继承自抽象类,该抽象类声明了一个纯虚拟方法,其名称与我们要强制覆盖的名称相同,则编译器将不允许实例化派生类型的对象,除非该方法实际上在派生类。

#include <iostream>

struct Base{
  virtual void print() {std::cout << "Base" << std::endl; }  
};

struct RequireOverride {
  virtual void print() = 0;   
};

struct D1: Base, RequireOverride {
  virtual void print() {std::cout << "D1" << std::endl; }  
};

struct D2: Base, RequireOverride {
  // no override of function print() results in a compilation error
  // when trying to instantiate D2
};


int main() {
  D1 d1;
  d1.print(); //ok


  //D2 d2; // ERROR: cannot declare variable 'd2' to be of abstract type 'D2'
           // because the following virtual functions are pure within 'D2':
           // virtual void RequireOverride::print()
  return 0;
}

如果要使用多个方法来强制存在替代,则可以将它们全部放入RequireOverride中,或定义更多结构以进行多重继承,例如RequireOverrideMethod1RequireOverrideMethod2,具体取决于上下文。

相关问题