c++ - 接口(interface)是 C++ 中的一个好习惯吗?

标签 c++

<分区>

来自 Java/python 世界,几乎没有或没有 C++ 经验,为了 Liskov substitution principle,我习惯于使用接口(interface)将类的契约与其实现分开。和 dependency injection .

我不打算详述 Java 中接口(interface)的所有好处,或者为什么引入它们(缺少多重继承)而在 C++ 中不需要它们 (see here for example)。 我还发现了如何拥有 equivalent of a Java interface in C++

我的问题更多是关于这在 C++ 环境中是否是一种好的做法。

据我了解,没有纯虚方法就不可能有接口(interface)的等价物。这意味着在 C++ 中引入接口(interface)会在代码中引入一些开销(因为虚拟方法 introduce an overhead )。

因此,基于纯虚方法的接口(interface)是不是一件好事?是否有其他方法可以实现我不知道的 Liskov 替换原则和依赖注入(inject)?也许使用模板?

例如google测试has it easy to mock virtual methods , 但提出了一种方式 mocking non virtual methods .

我想弄清楚我的编码习惯是否仍然适合我的新 C++ 环境,或者我是否应该适应和改变我的范例。

[根据答案和评论进行编辑]

我得到了我正在寻找的部分答案(即“是/否,有论据”),我想我应该进一步澄清我仍在努力弄清楚的内容

  • 除了使用类似接口(interface)的设计来进行依赖注入(inject)之外,是否有替代方案?
  • 反问这个问题:除了速度绝对至关重要的情况外,是否应该决定采用基于接口(interface)的设计,什么时候人们不想想要基于纯虚拟方法设计接口(interface)?<

注释:

  • 我想我想弄清楚我在界面方面的想法是否过于狭隘(因此我的编辑正在寻找替代方案)。
  • 我在 C++ 11 环境中工作

最佳答案

我想说接口(interface)在 C++ 中仍然是一个很好的实践。虚拟方法引入的开销是最小的,正如你会一次又一次听到的那样,过早的优化是一个大错误。抽象基类是 C++ 中一个众所周知、易于理解的概念,从长远来看,与复杂的模板元编程相比,支持可读、通用的概念可以极大地帮助您。

话虽如此,我会尽量避免多重继承。它有一些棘手的问题,这就是为什么 Java 明确禁止它进行常规继承的原因。一个简单的谷歌搜索可以给你更多的解释。

如果你有多个不相关的类并且你想在每个类上调用一个同名的方法(比如 foo()),那么你可以创建一个接口(interface)而不是接口(interface)模板化函数来执行此操作。

class A {
  void foo() {
    // do something
  }
};

class B {
  void foo() {
    // do something
  }
};

template <typename T>
void callFoo(const T& object) {
  object.foo();
}

int main() {
  A a;
  B b;
  callFoo(a);
  callFoo(b);

  return 0;
}

即使 callFoo() 中没有明确的“契约”声明该类型必须支持 .foo(),您传递给它的任何对象都必须支持否则会出现编译错误。这是一种在编译时对类型对象进行 duck 类型化的常用方法,也是某些场景下接口(interface)的替代方法。

归根结底,随着您学习更多 C++,您将根据自己的判断来决定如何实现您想要的多态行为。没有单一的正确答案如何去做,正如也没有错误的答案一样。抽象基类和模板鸭子类型都是很好的工具,但用途略有不同。

关于c++ - 接口(interface)是 C++ 中的一个好习惯吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58013017/

相关文章:

C++ 对象大小

c++ - 为什么在实践中向右移动在 Neon 和 SSE 中向左移动(反之亦然)?

c++ - 计算NS2中TCP的能耗

C++ Builder、TShapes、如何更改颜色 OnMouseEnter

c++ - 对数组的不同元素进行多次锁定

C++ fstream,从文本中读取数据并执行数学运算?

c++ - 在dll和exe中使用全局变量

c++ - 通过 Boost Asio 获取 UDP 数据报长度?

c++ - 如何用不同大小的 vector 初始化二维 vector

c++ - opengl 的投影和正交矩阵