c++ - 我应该停止使用抽象基类/接口(interface),而是使用 boost::function/std::function 吗?

标签 c++ stl c++11 design-patterns

我刚刚了解了 std::function 的真正含义以及它的用途,我有一个问题:现在我们基本上有了委托(delegate),我们应该在何时何地使用抽象基类以及何时,我们应该通过提供给泛型类的 std::function 对象来实现多态性吗? ABC在C++11中是否受到了致命一击?

到目前为止,我个人的经验是,切换委托(delegate)比为特定行为创建多个继承类要简单得多......所以我有点困惑,从现在开始抽象基会有多大用处。

最佳答案

更喜欢定义明确的接口(interface)而不是回调

std::function(以前的boost::function)的问题是大多数时候你需要一个类方法的回调,因此需要将 this 绑定(bind)到函数对象。但是在调用代码中,您无法知道 this 是否仍然存在。事实上,你甚至不知道有一个 this,因为 bind 已经将调用函数的签名塑造成调用者需要的东西。

这自然会导致奇怪的崩溃,因为回调会尝试触发不再存在的类的方法。

您当然可以使用 shared_from_this并将 shared_ptr 绑定(bind)到回调,但是您的实例可能永远不会消失。给您回电的人现在甚至在他们不知道的情况下参与了您的所有权。您可能想要更可预测的所有权和销毁。

另一个问题,即使您可以让回调正常工作,也就是使用回调,代码可能过于解耦。对象之间的关系很难确定以致代码可读性降低。然而,接口(interface)在适当的解耦级别与定义为接口(interface)契约的明确指定的关系之间提供了很好的折衷。在这种关系中,您还可以更清楚地指定诸如谁拥有谁、销毁顺序等问题。

std::function 的另一个问题是许多调试器不能很好地支持它们。在 VS2008 和 boost 函数中,你必须通过大约 7 层才能到达你的函数。即使所有其他条件都相同,回调是最好的选择,但不小心跨过 std::function 的目标所浪费的纯粹烦恼和时间也足以避免它。继承是该语言的核心特性,并且步入接口(interface)的重写方法是即时的。

最后,我将添加我们在 C++ 中没有委托(delegate)。 C# 中的委托(delegate)是该语言的核心部分,就像 C++ 和 C# 中的继承一样。我们有一个标准库功能,IMO 是从核心语言功能中删除的一层。因此,它不会与该语言的其他核心功能紧密集成。相反,它有助于将函数对象的概念形式化,这在一段时间内一直是 C++ 惯用语。

关于c++ - 我应该停止使用抽象基类/接口(interface),而是使用 boost::function/std::function 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9606236/

相关文章:

c++ - “如何使用 vi 跳转到 C++ 项目中的函数

c++ - 如何从 C++ 中的函数返回结构

c++ - 当我尝试清理STL vector 时发生未处理的异常

c++ - 查找项目是否已存在于 STL 队列中

c++ - Orderbook 表示的哪个 STL 容器?

multithreading - 环形缓冲区,1 个写入器和 N 个读取器

c++ - 使用删除方法在循环内重置迭代器

c++ - 字符串是 C++ 中的 char 吗?

c++ - C++中对象的继承和双端队列

c++ - 在 C++ 中计算 10^9 中的数字