我应该停止使用抽象基类/接口而是使用boost :: function/std :: function吗?

Zek*_*eks 12 c++ design-patterns stl c++11

我刚刚了解了std :: function到底是什么以及它用于什么,我有一个问题:现在我们基本上有代理,我们应该在何时何地使用抽象基类,何时我们应该实现多态性通过std :: function对象提供给泛型类?ABC在C++ 11中受到了致命打击吗?

就个人而言,到目前为止,我的经验是切换委托代码比为特定行为创建多个继承类要简单得多......所以我有点困惑abotu从现在起如何有用的Abstract Bases.

Dou*_* T. 19

更喜欢在回调上定义良好的接口

std::function(之前boost::function)的问题是大多数时候你需要对类方法进行回调,因此需要绑定this到函数对象.但是在调用代码中,您无法知道是否this仍然存在.实际上,你根本不知道是this因为bind已经将调用函数的签名模型化为调用者所需要的.

当回调试图触发不再存在的类的方法时,这自然会导致奇怪的崩溃.

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

另一个问题,即使你可以让回调工作正常,也有回调,代码可能太分离了.对象之间的关系可能很难确定代码可读性会降低.但是,接口在适当的解耦级别与接口合同定义的明确指定的关系之间提供了良好的折衷.在这种关系中,您还可以更明确地指出谁拥有谁,强制令等问题.

另一个问题std::function是许多调试器不能很好地支持它们.在VS2008和boost功能中,您必须通过大约7层来完成您的功能.即使所有其他事情都是平等的,回调是最好的选择,纯粹的烦恼和时间浪费意外地踩过目标std::function是足够的理由来避免它.继承是该语言的核心功能,并且进入一个重写的接口方法是即时的.

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