虚拟继承是否强制基类默认可构造?

2024-02-04

在下面的代码中,编译器正在请求基址class X to be 默认可构造。但是,如果我删除virtual来自继承的关键字类节点, 会员的访问权限m_x当然,变得含糊不清,但是默认构造函数 for class X不再需要。

这是什么原因呢?

#include <iostream>

struct Apply
{
    template< typename T >
    struct Node : virtual T    // this line contains the virtual inheritance
    {
        template< typename ...Args>
        Node( Args... args )
            : T( args... )
        {}
    };

    template < typename ...BaseClasses>
    struct Inheritance;

    template < typename FirstBaseClass, typename ...OtherBaseClasses>
    struct Inheritance< FirstBaseClass, OtherBaseClasses... >   : FirstBaseClass
            , Inheritance< OtherBaseClasses... >
    {
        template< typename ...Args>
        Inheritance( Args... args )
            : FirstBaseClass( args... )
            , Inheritance< OtherBaseClasses... >( args... )
        {

        }
    };
};

template < >
struct Apply::Inheritance< >
{
    template< typename ...Args>
    Inheritance( Args... args ){}
};

struct X
{
    X(int i){}

    int m_x;
};

struct A : Apply::Node< X >
{
    A( int i )
        : Apply::Node< X >( i )
        , m_a( i )
    {

    }
    int m_a;
};


struct B : Apply::Node< X >
{
    B( int i )
        : Apply::Node< X >( i )
        , m_b( i )
    { }

    int m_b;
};

struct C : Apply::Node< X >
{
    C( int i )
        : Apply::Node< X >( i )
        , m_c( i )
    { }

    int m_c;
};

struct Example : Apply::Inheritance< A, B, C >
{
    Example( int i )
        : Apply::Inheritance< A, B, C >( i )
    { }

    void print( ) const
    {
        // this line needs the virtual inheritance
        std::cout << m_x << std::endl;

        std::cout << m_a << std::endl;
        std::cout << m_b << std::endl;
        std::cout << m_c << std::endl;
    }
};

int main()
{
    Example ex( 10 );

    ex.print( );

    return 0;
}

类的初始化顺序如下 [class.base.init]:

在非委托构造函数中,初始化按以下顺序进行:
— 首先,仅对于最底层派生类 (1.8) 的构造函数,虚拟基类在 它们在基类有向无环图的深度优先从左到右遍历中出现的顺序, 其中“从左到右”是派生类基说明符列表中基类的出现顺序。

你的层次结构是A --> Node<X> --> X,所以首先要初始化的是X,因为它是一个虚拟基类。它没有在您的 mem-initializer 中指定,因此插入了隐式默认构造:

A( int i )
    : X() // <== implicit 
    , Node< X >( i )
    , m_a( i )
{

}

Since X不是默认可构造的,你会得到这个错误。您只需明确提供正确的内容即可解决此问题:

A( int i )
    : X(i)
    , Node< X >( i )
    , m_a( i )
{

你不必担心X被构造两次,因为虚拟基类仅为most派生类...这将是A并不是Node<X>.

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

虚拟继承是否强制基类默认可构造? 的相关文章

随机推荐

  • Webclient 双向使用二进制文件

    网络客户端 http msdn microsoft com en us library system net webclient 28v vs 95 29 aspx用于将指令文件 最多 1 兆字节 上传到服务器 并以二进制数据形式接收该操作
  • 将自定义对象附加到 Qt 中的 QStandardItem

    我在用着QTreeView向用户显示一些数据 我想要的是将一个实际对象附加到使用表示的每个节点QStandardItem 将对象引用保存到QStandardItem QStandardItem child new QStandardItem
  • Hibernate FetchMode SELECT 与 JOIN

    我有以下课程 Entity public class TestContentElementResponse Id GeneratedValue strategy GenerationType AUTO protected Long id O
  • 通过 SSL 传递时的 Cookie 安全性

    我是否正确地认为 如果您通过 SSL 加密请求传递会话 cookie 则该 cookie 只能由能够直接访问 cookie 发送到的计算机或发送 cookie 的服务器的攻击者读取 前提是他们无法破解加密 SSL 加密所有流量 包括标头 其
  • PHP - 未定义的变量

    我正在做一些练习PHP 和 MySQL 初学者塔克先生 在他的示例中一切正常 但在我的电脑上出现错误 注意 未定义变量 passwordRetrieved 在 C wamp www loginForm php 第 39 行 此示例的完整 P
  • 我们如何在VB.Net控制台应用程序中使用定时器控件?

    我正在尝试在控制台应用程序中使用计时器控件 Friend WithEvents XTIMER As System Windows Forms Timer 我正在设置它的所有属性 我已将间隔设置为 15000 毫秒 但即使我将计时器控件的启用
  • 无法在 windows7 上打开请求的 SVN 文件系统

    在 Windows 7 上使用 subversion 配置 apache httpd 时 出现以下错误 我已经安装了不同类型版本的 SVN 和 apache 我仍然面临这个问题 可以请有人帮助我解决这个问题 svn version 1 9
  • 向 MongoDB 中的 $lookup 结果添加一个字段

    我正在尝试使用 node js MongoDB 驱动程序向查找结果添加一个字段 用户有两种提要 1 他或她自己的提要和 2 共享提要 所以我需要同时获得两者 然后将它们结合起来 这是我原来的查询 效果很好 client db atlas c
  • 使用 Google Apps 脚本从 Google Firebase 写入 Google Sheets

    尝试检索存储在名为 条目 的节点下的 google firebase 中的表单条目 并使用 google 表格中的脚本编辑器附加到 google 表格 我已将 FirebaseApp 库添加到 Google Sheet 脚本编辑器中 然后我
  • 移动第二列中的 li 项目 - 仅限 CSS

    I have UL and LI列表和最大项目数为 10 如果超过 5 个项目 我试图将项目移动到第二列 并且只想使用 CSS 进行处理 我尝试使用 CSS3 Column 但它与所有项目一起进入第二列 如何做我确保将超过 5 个的项目移至
  • 在虚拟服务器上运行外部程序

    我想将可通过命令行 Linux 操作系统 访问的小程序安装到服务器并使用 PHP 运行它们 我想在我的机器上安装 Apache vhost 有没有办法在我的虚拟服务器 我的系统上运行这些外部应用程序 以便我可以尝试 PHP 调用 我们一直都
  • Jenkins CI:如何在 SVN 提交上触发构建

    我需要设置哪些插件和插件功能才能让我的 Jenkins 作业在代码提交到 SVN 项目时触发构建 我已经安装了标准 SVN 插件以及 SVN 标记插件 但我没有看到任何允许触发器配置的新功能 有两种方法可以解决这个问题 我最初推荐第一个选项
  • Rust 中比较函数的相等性

    我有一个函数 它接受一个数字作为参数 然后根据该数字返回一个函数 根据许多不同的情况 它可能会返回约 50 个函数中的任何一个 并且它应该返回哪个函数的情况变得非常复杂 因此 我想构建一些测试以确保返回正确的函数 到目前为止我所拥有的看起来
  • 更强大的点版本(重复)

    我知道如何录音q到寄存器中 但我想知道是否可以设置一些东西来快速调用最后一个录音 就像 调用最后一个简短的编辑命令 参见here https stackoverflow com questions 12566235 what can the
  • 正则表达式匹配具有两个或多个特殊字符的强密码

    我需要使用 javascript 正则表达式匹配密码字段 并满足以下要求 至少 15 个字符 两个或多个小写字母 两个或多个大写字母 两位或更多数字 以下两个或多个特殊字符 我有一个正则表达式可以处理大多数情况 15 2 d 2 a z 2
  • phpmyadmin 令牌不匹配导致长时间闲置

    我安装了phpMyAdmin 4 0 4 1在我本地的开发环境中 我设置了auth type to config 我还通过此设置提供身份验证要求 cfg Servers i auth type config cfg Servers i ho
  • Google Chrome 强制下载“f.txt”文件

    更新到 Chrome 40 0 2214 111 后 当我访问某些 Google 相关网站 例如http youtube com http youtube com并在视频之前看到广告 浏览器下载一个名为f txt 我没有安装任何 adblo
  • 未找到符号:_libintl_gettext

    我正在尝试使用 C 创建一个 NodeJS 模块node gyp 该软件包依赖于 GNU 的 Gettext 库 我目前使用的是 Mac OS X Mountain Lion 我尝试过通过手动 Homebrew 甚至 Fink 自己安装该软
  • Apple 的 iMessage 模板或向现有应用程序添加扩展之间有什么区别?

    我注意到 iOS 10 消息应用程序的创建有所不同 如果您使用创建一个新项目iMessage Application选择新项目的模板 Xcode 将创建两个目标 一个应用程序和一个扩展 但该项目无法运行 从第二张图片可以看出 底部的目标选择
  • 虚拟继承是否强制基类默认可构造?

    在下面的代码中 编译器正在请求基址class X to be 默认可构造 但是 如果我删除virtual来自继承的关键字类节点 会员的访问权限m x当然 变得含糊不清 但是默认构造函数 for class X不再需要 这是什么原因呢 inc