不使用纯虚函数的C ++接口

时间:2019-08-26 10:06:40

标签: c++ interface c++14 c++17

关于在c ++中接口类的表达,我有以下问题;

到目前为止,我了解到的是,如果我们想在c +中创建接口,我们将使用纯虚函数,即类似

class A_Interface {
      // pure virtual function
      virtual std::string helloWorld() = 0;
};

此问题已在SO中多次回答。

但是,如果我们具有复杂的多重继承级别,例如

A : A_Interface
B : A

C : B

D : C

有时我们不希望在所有子类中重写完全相同的纯虚方法,因为在某些情况下,基类实现就足够了。 而且,这非常困难且非常耗时,尤其是当我们处理数百个类时。

目前,我知道避免这种情况的唯一方法是使用普通的虚函数。这使我不必在所有派生类中实现“ helloWorld”功能, 但也会产生负面影响,在这种情况下,我需要指定默认行为,否则将出现类似“未定义引用”的错误。

class A_Interface {
      // pure virtual function
      virtual std::string helloWorld(){
            return "hello from A_interface class";
        };
};

我不确定此解决方案是否可以解决,因此不确定以下两个问题:

1)使用简单的虚函数而不是纯虚函数声明接口是否被认为是不好的做法?如果可以的话,您能详细说明为什么吗?

2)在这种情况下,有没有一种方法可以在基类中不提供默认实现的情况下声明虚函数,而是在派生类(即B)中提供至少一个(或多个实现), C和D。

不幸的是,我想第二个问题的答案是“否”,但是在继续我的代码之前,请先确定一下。我之所以这样问,是因为我覆盖了默认行为,是“ A”和“ B”类,在这种情况下,无论如何都不会使用“ A_Interface”类中的“ helloWorld”主体。

如果代码是通过以下使用-pedantic开关编译的,则相关问题。

set(CMAKE_VERBOSE_MAKEFILE true)
set (CMAKE_CXX_STANDARD 17)
add_definitions(-std=c++17 )


if(UNIX)
    add_definitions(" -pedantic -pedantic-errors -W ")
    add_definitions(" -Wall -Werror  ")
#    add_definitions(" -g  ")
endif(UNIX)

2 个答案:

答案 0 :(得分:2)

  

1)使用简单的虚函数而不是纯虚函数声明接口是否被认为是不好的做法?如果可以的话,您能详细说明为什么吗?

然后,您没有定义接口,或者最好说您不只是在创建接口,还在创建默认行为。取决于您的用例。

  

2)在这种情况下,有没有一种方法可以在基类中不提供默认实现的情况下声明虚函数,而是在派生类(即B)中提供至少一个(或多个实现), C和D。

当然。为什么不呢? A中的纯虚拟,B中的实现。否则我不明白这个问题。

答案 1 :(得分:2)

请记住,您可以在层次结构的任何位置定义虚拟方法,并且任何派生类也将继承实现。

根据您要实现的目标,您有一些选择:

1)在B中拆分AbstractB : A,它没有提供helloWorld()的实现,而ConcreteB : AbstractB提供了具体的实现。 现在,您可以选择是否从具有默认行为的类继承。

2)在AAInterface中拆分HelloWorldInterface界面。现在,您可以为HelloWorldInterface提供任何具体的实现,并以更适合您的方式继承。

无论如何,您并没有对用例进行足够的澄清,所以我无法更具体地提出解决方案。