【问题标题】:List-Initialization of a Subclass [duplicate]子类的列表初始化[重复]
【发布时间】:2022-10-25 16:43:05
【问题描述】:

我想通过列表初始化(https://en.cppreference.com/w/cpp/language/list_initialization)初始化一个作为 A 子类的 B 类

但是,它不是这样工作的:

struct A {
   int x;
};

struct B : public A {
};

int main()
{
   A a{ 1 }; // compiles
   B b{ 2 }; // doesn't compile
}

有没有办法通过列表初始化来初始化 B 的实例?

本质上,我想在不声明任何构造函数的情况下初始化 B 的实例。

【问题讨论】:

  • 是否要将 B 保留为聚合?
  • @NathanOliver 我更喜欢这样。本质上,我想用值初始化子类而不声明任何构造函数。我更新了问题以使其更清楚。
  • "有没有办法通过列表初始化来初始化 B 的实例?" 使用 c++17。

标签: c++ inheritance compiler-errors aggregate list-initialization


【解决方案1】:

问题是您使用的是 C++ 编译器,该编译器基于 C++ 17 标准之前的 C++ 标准编译程序。

在 C++ 17 标准之前,聚合可能不包含基类。

因此,请使用至少设置 C++ 17 标准规范的编译器选项。

根据 C++ 14 标准(8.5.1 聚合)

1 聚合是没有用户提供的数组或类(第 9 条) 构造函数(12.1),没有私有或受保护的非静态数据成员 (第 11 条),没有基类(第 10 条),并且没有虚函数 (10.3)。

从 C++ 17 开始,标准聚合允许有基类(11.6.1 聚合)

1 聚合是一个数组或一个类(第 12 条)

(1.1) — 没有用户提供的、显式的或继承的构造函数 (15.1),

(1.2) — 没有私有或受保护的非静态数据成员(第 14 条),

(1.3) — 没有虚函数 (13.3),并且

(1.4) — 没有虚拟、私有或受保护的基类 (13.1)。

另请注意,根据 C++17 和 C++20 标准中的聚合存在差异。例如,在 C++ 17 中,您可以使用说明符 default 为聚合声明构造函数。

就是这个程序

struct A {
   int x;
};

struct B : public A {
    B() = default;
};

int main()
{
   A a{ 1 }; 
   B b{ 2 }; 
}

根据 C++ 17 标准有效,根据 C++20 标准无效。

但是,如果您将使用说明符 explicit 声明构造函数

struct B : public A {
   explicit  B() = default;
};

那么即使根据 C++ 17 标准,该程序也将无效。

【讨论】:

  • 显然,编译器开发人员和我同意应该可以像这样实例化子类:感谢您的快速响应,它有效!
  • @Urquhart 一点也不。我们,初学者,应该互相帮助。:)
猜你喜欢
  • 2012-09-29
  • 2015-09-25
  • 2011-06-18
  • 2013-02-10
  • 1970-01-01
  • 2017-01-14
  • 2017-10-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多