聚合初始化绕过私有类构造函数

问题描述 投票:0回答:2

我一直认为聚合初始化是为了让编码人员免于编写自定义构造函数。然而,这似乎“潜入”了私有构造函数的“安全旁路”。

假设我有

class A
,我只想由
class B
创建。

struct A
{
  friend class B;
  const int i, k;
private:
  A () = default;
};

class B
{
public:
  A what () { return {1, 2}; }
};

int main ()
{
  B b {};
  A a {2,3}; // oh no
  return 0;
}

上面的示例编译并运行良好,通过使用大括号,我可以非常轻松地在任何地方创建一个

A
对象。

防止这种情况的唯一方法是编写一个用户构造函数,然后完全取消聚合初始化。

所以我的问题是:聚合初始化是默认的“hidden”构造函数吗

public

实例:https://onlinegdb.com/r1jHLxzRD

没有答案的类似问题:私有聚合初始化

c++ private friend aggregate-initialization
2个回答
5
投票

我一直认为聚合初始化是为了让程序员免于编写自定义构造函数。

这是聚合初始化实现的目标,但将其定义为聚合初始化的目的过于简单化。

然而,这似乎“潜入”了私有构造函数的“安全旁路”。

这种使用私有(甚至删除!)默认构造函数进行聚合的偷偷摸摸的情况是在 C++11 中通过引入默认(和删除)成员函数而引入的。它不再存在于 C++20 中,其中

A
不再是聚合。

所以我的问题是:聚合初始化是一个“隐藏”构造函数吗

我将聚合初始化描述为根本不使用构造函数。相反,成员是直接初始化的。


0
投票

您可以通过设置默认构造函数来禁用聚合初始化

explicit
:

explicit  A () = default;

这适用于 C++11、C++14、C++17、C++20 和 C++23。

© www.soinside.com 2019 - 2024. All rights reserved.