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

2023-12-31

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

就我个人而言,到目前为止的经验是,切换委托比为特定行为创建多个继承类要简单得多……所以我对从现在开始抽象基的有用性感到有点困惑。


优先选择定义良好的接口而不是回调

问题在于std::function(之前boost::function)是大多数时候你需要回调一个类方法,因此需要绑定this到函数对象。然而在调用代码中,你无法知道是否this还在附近。事实上,你根本不知道还有一个this因为bind已经将调用函数的签名塑造成调用者所需要的。

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

你当然可以使用shared_from_this http://www.boost.org/doc/libs/1_40_0/libs/smart_ptr/enable_shared_from_this.html并将shared_ptr绑定到回调,但是你的实例可能永远不会消失。给您回电的人现在就参与了您的所有权,而他们甚至不知道这一点。您可能想要更可预测的所有权和破坏。

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

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我应该停止使用抽象基类/接口,而是使用 boost::function/std::function 吗? 的相关文章

  • 类型中的属性名称必须是唯一的

    我正在使用 Entity Framework 5 并且有以下实体 public class User public Int32 Id get set public String Username get set public virtual
  • 如何在 Cassandra 中存储无符号整数?

    我通过 Datastax 驱动程序在 Cassandra 中存储一些数据 并且需要存储无符号 16 位和 32 位整数 对于无符号 16 位整数 我可以轻松地将它们存储为有符号 32 位整数 并根据需要进行转换 然而 对于无符号 64 位整
  • 如何从 Visual Studio 将视图导航到其控制器?

    问题是解决方案资源管理器上有 29 个项目 而且项目同时具有 ASP NET MVC 和 ASP NET Web 表单结构 在MVC部分中 Controller文件夹中有大约100个子文件夹 每个文件夹至少有3 4个控制器 视图完全位于不同
  • free 和 malloc 在 C 中如何工作?

    我试图弄清楚如果我尝试 从中间 释放指针会发生什么 例如 看下面的代码 char ptr char malloc 10 sizeof char for char i 0 i lt 10 i ptr i i 10 ptr ptr ptr pt
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 需要帮助优化算法 - 两百万以下所有素数的总和

    我正在尝试做一个欧拉计划 http projecteuler net问题 我正在寻找 2 000 000 以下所有素数的总和 这就是我所拥有的 int main int argc char argv unsigned long int su
  • 访问外部窗口句柄

    我当前正在处理的程序有问题 这是由于 vista Windows 7 中增强的安全性引起的 特别是 UIPI 它阻止完整性级别较低的窗口与较高完整性级别的窗口 对话 就我而言 我想告诉具有高完整性级别的窗口进入我们的应用程序 它在 XP 或
  • 重载 (c)begin/(c)end

    我试图超载 c begin c end类的函数 以便能够调用 C 11 基于范围的 for 循环 它在大多数情况下都有效 但我无法理解和解决其中一个问题 for auto const point fProjectData gt getPoi
  • 方程“a + bx = c + dy”的积分解

    在等式中a bx c dy 所有变量都是整数 a b c and d是已知的 我如何找到整体解决方案x and y 如果我的想法是正确的 将会有无限多个解 由最小公倍数分隔b and d 但我只需要一个解决方案 我可以计算其余的 这是一个例
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • WcfSvcHost 的跨域异常

    对于另一个跨域问题 我深表歉意 我一整天都在与这个问题作斗争 现在已经到了沸腾的地步 我有一个 Silverlight 应用程序项目 SLApp1 一个用于托管 Silverlight SLApp1 Web 的 Web 项目和 WCF 项目
  • x:将 ViewModel 方法绑定到 DataTemplate 内的事件

    我基本上问同样的问题这个人 https stackoverflow com questions 10752448 binding to viewmodels property from a template 但在较新的背景下x Bind V
  • C 函数 time() 如何处理秒的小数部分?

    The time 函数将返回自 1970 年以来的秒数 我想知道它如何对返回的秒数进行舍入 例如 对于100 4s 它会返回100还是101 有明确的定义吗 ISO C标准没有说太多 它只说time 回报 该实现对当前日历时间的最佳近似 结
  • 编译时展开 for 循环内的模板参数?

    维基百科 here http en wikipedia org wiki Template metaprogramming Compile time code optimization 给出了 for 循环的编译时展开 我想知道我们是否可以
  • 在 WPF 中使用 ReactiveUI 提供长时间运行命令反馈的正确方法

    我有一个 C WPF NET 4 5 应用程序 用户将用它来打开某些文件 然后 应用程序将经历很多动作 读取文件 通过许多插件和解析器传递它 这些文件可能相当大 gt 100MB 因此这可能需要一段时间 我想让用户了解 UI 中发生的情况
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • C# 使用“?” if else 语句设置值这叫什么

    嘿 我刚刚看到以下声明 return name null name NA 我只是想知道这在 NET 中叫什么 是吗 代表即然后执行此操作 这是一个俗称的 条件运算符 三元运算符 http en wikipedia org wiki Tern
  • 在Android Studio gradle项目中使用NDK和STL

    我在将 stlport 链接到 Android Studio 中的 gradle 项目时遇到问题 使用 NDK 的 Eclipse Android 项目迁移到 Android Studio 该项目使用 STL 我有包含内容的 android
  • DotNetZip:如何提取文件,但忽略zip文件中的路径?

    尝试将文件提取到给定文件夹 忽略 zip 文件中的路径 但似乎没有办法 考虑到其中实现的所有其他好东西 这似乎是一个相当基本的要求 我缺少什么 代码是 using Ionic Zip ZipFile zf Ionic Zip ZipFile
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前

随机推荐