施工期间的虚拟功能解决方法

2023-11-29

我有一个具有虚函数的基类。我想在构造过程中调用该类,因为我希望为每个派生类调用该函数。我知道我无法在构造过程中调用虚拟函数,但我想不出一个优雅的(即避免重复代码)解决方案。

在构造过程中调用虚函数有哪些解决方法?

我想避免这种情况的原因是因为我不想创建只调用基类的构造函数。

class A {
    public:
        A() {
            read();
        }

        // This never needs to be called
        virtual void read() = 0;
}

class B:A {
    public:
        B():A() {   };
        read() { /*Do something special for B here.*/ }

}

class C:A {
    public:
        C():A() {   };
        read() { /*Do something special for C here.*/ }

}

PS:Python 的做法很简单raise NotImplementedError in A::read()。我正在回归 C++,但我比我想象的还要生疏。


常见问题解答的角度。

这是一个常见问题。

请参阅标题为“C++ 常见问题解答”的项目“好吧,但是有没有一种方法可以模拟这种行为,就好像动态绑定在我的基类构造函数中的 this 对象上起作用一样?”.

在提问之前检查常见问题解答(通常是谷歌搜索或 altavista)通常是个好主意。


问题为“派生类特定基初始化”。

需要明确的是,虽然上面的字面问题是

“在构造过程中调用虚拟函数有哪些解决方法?”

很明显,意思是

“基类怎么能B被设计成每个派生类都可以指定期间发生的事情的一部分B建造?”

一个主要的例子是 C 风格的 GUI 功能由 C++ 类包装。然后是将军Widget构造函数可能需要实例化一个 API 级小部件,根据最派生的类,该小部件应该是按钮小部件或列表框小部件或其他什么。因此,最派生的类必须以某种方式影响发生的事情Widget的构造函数。

换句话说,我们正在谈论派生类特定的基础构造.

Marshall Cline 称之为“构造期间动态绑定”,这在 C++ 中是有问题的,因为在 C++ 中,类中对象的动态类型T建设和破坏,是T。这有助于类型安全,因为在子对象已初始化或其初始化开始之前,不会在派生类子对象上调用虚拟成员函数。但主要成本是 DBDI(显然)无法以既简单又安全的方式完成。


可以在其中执行派生类特定的 init。

在问题中,派生类的特定操作被称为read。这里我称之为derived_action。有 3 个主要的可能性derived_action被调用:

  • 由实例化代码调用,称为分两期建设.
    这本质上意味着手头有一个几乎不可用的未完全初始化的对象的可能性,一个僵尸对象。然而,随着 C++11 移动语义变得更加常见和接受(无论如何,可以通过使用工厂在一定程度上缓解它)。主要问题是,在构造的第二阶段,由于构造期间的动态类型更改,不存在针对未初始化子对象的虚拟调用的普通 C++ 保护。

  • 调用者Derived构造函数。
    例如,derived_action可以作为参数表达式调用Base构造函数。一种并非完全不常见的技术是使用类模板来生成大多数派生类,例如供应电话derived_action.

  • 调用者Base构造函数。
    这意味着知识derived_action必须动态或静态地传递给构造函数。一个好的方法是使用默认的构造函数参数。这导致了并行类层次结构的概念,即派生类操作的层次结构。

这个列表是按照复杂性和类型安全性逐渐提高的顺序排列的,而且据我所知,还反映了各种技术的历史使用情况。

例如。 1990 年初,在 Microsoft 的 MFC 和 Borland 的 ObjectWindows GUI 中,两阶段构建的库很常见,而截至 2014 年,这种设计现在被认为是非常糟糕的。

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

施工期间的虚拟功能解决方法 的相关文章

  • 检查两个数是否是彼此的排列?

    给定两个数字 a b 使得 1 例如 123 是 312 的有效排列 我也不想对数字中的数字进行排序 如果您指的是数字的字符 例如 1927 和 9721 则 至少 有几种方法 如果允许排序 一种方法是简单地sprintf将它们放入两个缓冲
  • 如何使 Windows 窗体的关闭按钮不关闭窗体但使其不可见?

    该表单有一个 NotifyIcon 对象 当用户单击 关闭 按钮时 我希望表单不关闭而是变得不可见 然后 如果用户想再次查看该表单 可以双击系统托盘中的图标 如果用户想关闭表单 可以右键单击该图标并选择 关闭 有人可以告诉我如何使关闭按钮不
  • 当我使用“control-c”关闭发送对等方的套接字时,为什么接收对等方的套接字不断接收“”

    我是套接字编程的新手 我知道使用 control c 关闭套接字是一个坏习惯 但是为什么在我使用 control c 关闭发送进程后 接收方上的套接字不断接收 在 control c 退出进程后 发送方的套接字不应该关闭吗 谢谢 我知道使用
  • 将数组向左或向右旋转一定数量的位置,复杂度为 o(n)

    我想编写一个程序 根据用户的输入 正 gt 负 include
  • UML类图:抽象方法和属性是这样写的吗?

    当我第一次为一个小型 C 项目创建 uml 类图时 我在属性方面遇到了一些麻烦 最后我只是将属性添加为变量 lt
  • 使闭包捕获的变量变得易失性

    闭包捕获的变量如何与不同线程交互 在下面的示例代码中 我想将totalEvents 声明为易失性的 但C 不允许这样做 是的 我知道这是错误的代码 这只是一个例子 private void WaitFor10Events volatile
  • 将布尔参数传递给 SQL Server 存储过程

    我早些时候问过这个问题 我以为我找到了问题所在 但我没有 我在将布尔参数传递给存储过程时遇到问题 这是我的 C 代码 public bool upload false protected void showDate object sende
  • 为什么#pragma optimize("", off)

    我正在审查一个 C MFC 项目 在某些文件的开头有这样一行 pragma optimize off 我知道这会关闭所有以下功能的优化 但这样做的动机通常是什么 我专门使用它来在一组特定代码中获得更好的调试信息 并在优化的情况下编译应用程序
  • 指针问题(仅在发布版本中)

    不确定如何描述这一点 但我在这里 由于某种原因 当尝试创建我的游戏的发布版本进行测试时 它的敌人创建方面不起作用 Enemies e level1 3 e level1 0 Enemies sdlLib 500 2 3 128 250 32
  • C - 找到极限之间的所有友好数字

    首先是定义 一对友好的数字由两个不同的整数组成 其中 第一个整数的除数之和等于第二个整数 并且 第二个整数的除数之和等于第一个整数 完美数是等于其自身约数之和的数 我想做的是制作一个程序 询问用户一个下限和一个上限 然后向他 她提供这两个限
  • C#:如何防止主窗体过早显示

    在我的 main 方法中 我像往常一样启动主窗体 Application EnableVisualStyles Application SetCompatibleTextRenderingDefault false Application
  • Web API - 访问 DbContext 类中的 HttpContext

    在我的 C Web API 应用程序中 我添加了CreatedDate and CreatedBy所有表中的列 现在 每当在任何表中添加新记录时 我想填充这些列 为此目的我已经覆盖SaveChanges and SaveChangesAsy
  • 在 ASP.NET Core 3.1 中使用包含“System.Web.HttpContext”的旧项目

    我们有一些用 Net Framework编写的遗留项目 应该由由ASP NET Core3 1编写的API项目使用 问题是这些遗留项目正在使用 System Web HttpContext 您知道它不再存在于 net core 中 现在我们
  • Github Action 在运行可执行文件时卡住

    我正在尝试设置运行google tests on a C repository using Github Actions正在运行的Windows Latest 构建过程完成 但是当运行测试时 它被卡住并且不执行从生成的可执行文件Visual
  • 如何衡量两个字符串之间的相似度? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 给定两个字符串text1 and text2 public SOMEUSABLERETURNTYPE Compare string t
  • 如何使我的表单标题栏遵循 Windows 深色主题?

    我已经下载了Windows 10更新包括黑暗主题 文件资源管理器等都是深色主题 但是当我创建自己的 C 表单应用程序时 标题栏是亮白色的 如何使我自己的桌面应用程序遵循我在 Windows 中设置的深色主题 你需要调用DwmSetWindo
  • 插入记录后如何从SQL Server获取Identity值

    我在数据库中添加一条记录identity价值 我想在插入后获取身份值 我不想通过存储过程来做到这一点 这是我的代码 SQLString INSERT INTO myTable SQLString Cal1 Cal2 Cal3 Cal4 SQ
  • ASP.NET MVC 6 (ASP.NET 5) 中的 Application_PreSendRequestHeaders 和 Application_BeginRequest

    如何在 ASP NET 5 MVC6 中使用这些方法 在 MVC5 中 我在 Global asax 中使用了它 现在呢 也许是入门班 protected void Application PreSendRequestHeaders obj
  • 限制C#中的并行线程数

    我正在编写一个 C 程序来生成并通过 FTP 上传 50 万个文件 我想并行处理4个文件 因为机器有4个核心 文件生成需要更长的时间 是否可以将以下 Powershell 示例转换为 C 或者是否有更好的框架 例如 C 中的 Actor 框
  • 使用按位运算符相乘

    我想知道如何使用按位运算符将一系列二进制位相乘 但是 我有兴趣这样做来查找二进制值的十进制小数值 这是我正在尝试做的一个例子 假设 1010010 我想使用每个单独的位 以便将其计算为 1 2 1 0 2 2 1 2 3 0 2 4 虽然我

随机推荐

  • 如何从用Java编写的AWS Lambda函数读取S3文件? [复制]

    这个问题在这里已经有答案了 我编写了一个 AWS Lambda 函数 它的目标是在调用时 它读取 x db 文件的内容 从中获取特定值并返回给调用者 但是这个 x db 文件会不时更改 所以我想将这个 x db 文件上传到 S3 并从 AW
  • 如何使用 C++ API 将元数据字符串添加到 LLVM 模块?

    我正在尝试添加一个元数据字符串到我的 LLVM 模块 我正在尝试的精简版本是 include
  • 如何使用 Python urllib2 下载分块数据

    我正在尝试使用 Python 2 从服务器下载一个大文件 req urllib2 Request https myserver mylargefile gz rsp urllib2 urlopen req data rsp read 服务器
  • 在reactjs中循环获取

    所以基本上我创建了一个循环 它从数组中获取值并使用 youtube api 将这些值放入循环中 如果我从循环内访问它 youtube 链接工作正常 但在循环外 当我运行 console log urllist 时 我得到一个空数组 我想做的
  • 空手道:使用重试时有没有办法禁用日志?

    我正在使用空手道进行验证测试 我对我的一个请求设置了重试 但有时重试次数超过 100 次 这会创建大量无用的日志 每个请求上的负载相同 这让我的 CI 变得臃肿 我想减少此日志数量 也许可以仅针对此请求禁用日志 我试过了 configure
  • 在 Jackson 中反序列化 ISO8601 格式的“Zulu”时间

    我需要反序列化格式时间2016 11 28T10 34 25 097Z使用Jackson进入Java8的ZonedDateTime 我相信我正确配置了 ObjectMapper 工厂方法 Bean ObjectMapper getObjec
  • 将 Iterable 转换为 Collection 的简单方法

    在我的应用程序中 我使用第 3 方库 Spring Data for MongoDB准确地说 该库的方法返回Iterable
  • 等待unity3d中的动画完成

    我有一个动画在Update 函数 在Switch case 动画完成后 布尔值将被设置为 true My code case play animation Play play gobool true startbool false brea
  • android volley 发布二进制正文

    场景 在帖子正文中上传二进制数据 处理包含 JSON 的响应正文 如何使用 Volley 执行以下操作 curl X POST H X Application Id 3KxPB H X REST API Key jkuI9 H Conten
  • 在 React-Router 中使用 Link 传递 props

    你好 我正在尝试将 Props 传递给Details带有 React Router 的 Link 组件的组件 我不想显示Detail页面上的组件 它应该在单击按钮时呈现 但当新组件呈现时 url 也应该类似于 details KvhNJec
  • 用于非游戏相关 3D 图形编程的托管 Direct3D 或 XNA?

    哪种是进行 NET 3D 图形编程的首选方法 Direct3D 或 XNA 似乎是当前的技术 但哪一种最适合非游戏相关的编程 另外 Managed Direct 3D 是否已经停止 XNA 似乎并不真正适合非游戏开发 是的 可惜 MS 停止
  • Windows 7 任务栏中的 Delphi 窗体图标模糊

    I have an application having 2 Forms each Form and Application have individual Icon On Form1BitBtn1 Click Form2 is Shown
  • 如何在 webview2 中检测鼠标点击 (c#/vb.net)

    我尝试获取 html 元素的单击事件 我使用的网络浏览器 instance Nothing instance WebBrowser1 Document AddHandler instance Click AddressOf Document
  • 在代码隐藏中绑定动态创建的控件

    我动态创建了在运行时在 C 代码后面创建的弹出窗口 其中填充了 xaml 中的内容 并且很难在后面的代码中绑定它们 现在 当它被创建时 它会循环遍历 xaml 中的项目并为每个项目创建一个关联的复选框 ListView listView n
  • 是什么使

    周围似乎有某种魔力
  • 无法获取移动服务的位置信息 - 错误 400

    我尝试按照 Scotts 在此页面上对 Azure 的介绍进行操作 https www windowsazure com en us develop mobile tutorials get started 但在第 4 点 当我打算创建新的
  • Mysql 查询 - 使用 join/union 等

    我的数据库中有 4 个表 名为顾客 保存他们的个人详细信息以及他们在哪个项目中的哪个房间 payments 持有该项目的付款详细信息 projects 持有项目详细信息 和staff 持有员工登录信息 我还有 3 个页面 我从所有这些页面中
  • mysql命名约定

    我通常总是使用某种Hungarian Notation对于我的表中的字段名称 例如 Table Users u id u name u email etc Posts p id p u id p title p content etc 但最
  • Node.js Express:对 ejs 模板感到困惑

    我把我的ejs模板文件在views文件夹如 views foo html layout html 所以我配置我的 ejs 模板 app set views dirname views app engine html require ejs
  • 施工期间的虚拟功能解决方法

    我有一个具有虚函数的基类 我想在构造过程中调用该类 因为我希望为每个派生类调用该函数 我知道我无法在构造过程中调用虚拟函数 但我想不出一个优雅的 即避免重复代码 解决方案 在构造过程中调用虚函数有哪些解决方法 我想避免这种情况的原因是因为我