虚拟继承 - 跳过构造函数

2024-05-06

我有以下课程:

class Socket
{
    Socket();
    Socket( SOCKET s );
};

class Connection : public virtual Socket
{
    Connection( IP ip );
};

这两个类包含一些纯虚函数和一些非虚函数以及它们自己的一些数据。它们的重点是我将派生一些套接字类型,实现不同的协议。

所以我专门研究这两类:

class ProtocolSocket : public virtual Socket
{
    ProtocolSocket() {}
    ProtocolSocket( SOCKET s ) : Socket( s ) { ; }
};

class ProtocolConnection : public ProtocolSocket, public virtual Connection
{
    ProtocolConnection( SOCKET s, IP ip ) : ProtocolSocket( s ), Connection( ip ) {;}
};

出了问题——我相信你们很多人都能看到。我尝试创建一个 ProtocolConnection:

new ProtocolConnection( s, ip );

施工过程如下:

start ctor ProtocolConnection
    start ctor Connection
       start ctor Socket
          Socket(); - default ctor via Connection's init list
       end ctor Socket
       Connection(); - default ctor ProtocolConnection's init list
    end ctor Connection
    start ctor ProtocolSocket
       start ctor Socket     
          // Socket( s ); - skipped!!! - would have been from init 
          //                list of ProtocolSocket, but ctor for this object 
          //                already called!
       end ctor Socket
       ProtocolSocket( s ); -from init list of ProtocolConnection()
    end ctor ProtocolSocket
    ProtocolConnection( s, ip );
end ctor ProtocolConnection

跳过第二个 Socket 构造函数是语言规范所说应该发生的事情,并且有充分的理由。

如何让它调用构造函数并调用 Socket( s ),而不是之前的构造函数?

我打算有多个派生类,例如还有OtherProtocolSocket 和OtherProcolConnection,与ProtocoSocket 和ProtocolConnection 对象处于同一级别。

我想要实现的效果是我想要构造 ProtocolSocket 和 ProtocolConnection 对象,然后将它们作为 Socket 和 Connection 对象在我的系统中传递。因此,在我创建了一个实现给定协议的套接字后,我只需对其进行读取和写入,而不必担心底层协议的细节。

Connection对象需要继承Socket对象的所有方法。

@UPDATE:

DyP 建议在 ProtocolConnection 中添加 Socket 的初始化程序。这解决了问题。我会给你一个接受......但这只是在评论中。


要记住的关键是,虚拟基类的构造函数是作为最派生类初始化的一部分完成的(并且在构造其他基类之前)。所以你的施工订单幻灯片不正确。

事实上,当您构造 ProtocolConnection 时,它首先构造 Socket,然后是 Connection(因为您实际上继承了它),最后是 ProtcolSocket。

要调用所需套接字的构造函数,您需要将其构造函数作为 ProtocolSocket 成员初始值设定项列表的一部分进行调用,如下所示

class ProtocolConnection: public ProtocolSocket, public virtual Connection
{
    public:
    ProtocolConnection(int s, int ip) :
        Socket(s), Connection(ip), ProtocolSocket(s)  
        // Note, also reordered, since all virtual bases are initialized before the
        // non-virtual bases
    {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
};

最后,作为注释,我建议简化您的继承层次结构。特别是,虚拟继承和使用多个构造函数使因素变得复杂。

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

虚拟继承 - 跳过构造函数 的相关文章

随机推荐

  • 强制使用原生 Knockout 模板

    我有一个需要 jQuery tmpl 的页面 但我想使用本机淘汰模板 data bind foreach Comments 属性 因为我已经包含了 jQuery tmpl 所以淘汰赛的本机模板被禁用 有没有办法可以强制使用本机功能 Than
  • Postgis安装:类型“几何”不存在

    我正在尝试使用 Postgis 创建表 我按这个做page http postgis refractions net documentation manual 1 5 ch02 html id2619431 但是当我导入 postgis s
  • Visual Studio Code - 无法启动浏览器:“无法在您的系统上找到浏览器的安装。”

    最近在 VS code 中运行脚本 我的任何 python javascript html 脚本 时出现了一个问题 出现一个弹出窗口 Visual Studio Code Unable to launch Browser Unable to
  • nginx 反向代理 websocket

    nginx 现在支持代理 websockets 但我无法找到任何有关如何在没有单独的情况下执行此操作的信息location应用于使用 websocket 的 URI 的块 我见过一些人推荐这种方法的一些变体 location proxy h
  • 另一个数组内的 stdClass 对象数组

    我正在尝试从下面的 array1 获取信息 通过执行以下操作 我可以毫无问题地获取场地名称和地点地址 array2 array array3 array foreach array1 as item array2 item gt venue
  • lwjgl 3 , glUniformMatrix4 导致 jre 崩溃

    我正在使用 lwjgl 3 并学习现代 opengl 3 我想将统一矩阵发送到顶点着色器 以便我可以应用转换 我尝试过 但程序因此错误而崩溃 A fatal error has been detected by the Java Runti
  • mpld3图,注释问题

    我正在使用 mpld3 在 Intranet 网站上显示图形 我正在使用将图形保存到字典并使用 mpld3 js 在客户端渲染它的选项 除非我想使用注释 否则该图呈现良好 这些显然是抵消的 我不明白为什么 因为即使我将偏移量设置为 0 0
  • 升压参数库

    最近我发现参数 http www boost org doc libs 1 50 0 libs parameter doc html index htmlBoost 中的库 老实说 我不明白为什么这是 Boost 的一部分 当需要向函数传递
  • 如何只应用一种 clang-format 操作?

    我想用clang 格式调整我的评论 但仅此而已 选项是 AlignTrailingComments bool 但是当我运行以下命令时 clang format 3 6 i style AlignTrailingComments true
  • 获取无平方数的列表

    获得该值的一种方法是自然数 1 n 我们对每个因子进行因式分解 看看它们是否有重复的质因数 但这对于大的情况来说会花费很多时间n 那么有没有更好的方法从 1 中获取无平方数n 您可以使用埃拉托斯特尼筛法的修改版本 取一个布尔数组 1 n 预
  • 如何将typescript添加到Vue 3和Vite项目中

    我的设置 我通过以下方式安装了 Vue 和 Vite创建 vite 应用程序模块 然后将 init vite app 生成的所有包更新为 Vue 和 Vite 的最新 RC 版本 现在我想对我的所有代码使用打字稿 首先我只是玩了一下 然后添
  • 横切关注点示例

    什么是一个很好的例子cross cutting concern 医疗记录示例维基百科 http en wikipedia org wiki Cross cutting concern页面对我来说似乎不完整 具体来说 从这个例子来看 为什么日
  • 规范注册 ID 和消息 ID 格式

    我的理解有问题Canonical Registration Id并让谷歌返回它 我特意注册了两次我的Android应用程序 以测试Canonical Registration Id 但是当我尝试向两者推送消息时Registration Id
  • 为什么需要为每个线程创建 ABAddressbookRef?

    苹果说 重要提示 ABAddressBookRef 的实例不能被多个使用 线程 每个线程必须创建自己的实例 But why 我知道某些特定的类或操作必须在主线程中完成 而且我知道有些对象不是线程安全的 这意味着如果这些对象同时被两个不同的线
  • 创建一个跨浏览器 mixin 进行转换:旋转

    我想为 sass 创建一个 mixin 它将对指定元素应用旋转 mixin 应采用一个参数 表示要应用的旋转度数 从 css3please com 我找到了一种使用 CSS 实现此功能的跨浏览器方法 box rotate moz trans
  • 如何从特定 Sourceforge 项目下载所有文件?

    在花了大约一个小时从 sourceforge 下载几乎每个 Msys 包之后 我想知道是否有更聪明的方法来做到这一点 是否可以使用 wget 来实现此目的 我已经成功地使用了这个脚本 https github com SpiritQuadd
  • 文件/文件夹结构的递归搜索

    我正在尝试为返回文件和文件夹列表的 Web 服务构建递归搜索功能 我创建了这两个方法 因此它们充当递归搜索 它首先获取顶级内容 然后将任何文件添加到 fileList 并将任何子文件夹添加到 subFoldersList 我们传入访问级别
  • 无限滚动 jQuery 和 Laravel 5 分页

    我成功从控制器返回数据 public function index posts Post with status verified gt paginate 30 return view show gt with compact posts
  • 使用 PSEXEC 远程启动和停止 Windows 服务

    如何使用 PSEXEC 远程启动和停止 Windows 服务 最好是编写语法我尝试了下面给出的 cmdlet psexec Server u Administrator p Somepassword ServiceName SysInter
  • 虚拟继承 - 跳过构造函数

    我有以下课程 class Socket Socket Socket SOCKET s class Connection public virtual Socket Connection IP ip 这两个类包含一些纯虚函数和一些非虚函数以及