【问题标题】:Can't C++ POD type have any constructor?C++ POD 类型不能有任何构造函数吗?
【发布时间】:2011-03-26 13:48:40
【问题描述】:

我有一个类和一个 const 变量。

struct A 
{
    int b;
};

A const a;

A类是POD,可以这样初始化。

A const a = { 3 };

恕我直言,拥有这样的构造函数看起来不错。

struct A 
{
    int b;

    A(int newB) : b(newB)
    {
    }
};

但是 Clang 假定 A 是非聚合类型。为什么我不能有这样的构造函数?还是我应该做点别的?


我修改了问题以表达我原来的意思。我错误地将struct 写成了class,对于@Johannes 的混淆感到抱歉:)

【问题讨论】:

  • Eonil:我相信,我的回答澄清了你所有的疑惑,尤其是标准的引用。
  • 您需要确定您的问题是什么:1) POD 类型或 2) 只需使用 {} 初始化程序(即聚合)的能力。目前还不清楚具体是什么问题。
  • @Nawaz 感谢您的关心。你的答案就是我想要的!
  • @AndreyT 我的问题是关于 POD 类型的构造函数。我曾想使用构造函数语法而不是 {...} 语法。但现在我知道我的想法是错误的。
  • @AndreT:两者不一样吗?在我看来,在 C++03 中,只有聚合(即它的所有变体)可以用 {}? 初始化。而聚合类不过是 POD 类,对吧?

标签: c++


【解决方案1】:

POD 表示普通旧数据类型,根据定义不能有用户定义的构造函数。

POD 实际上是一个聚合类型(见下一段引文)。那么什么是聚合? C++ 标准在第 8.5.1/1 节中说,

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

C++ 标准的第 9/4 节说,

[....] POD 结构是一个聚合类,没有非静态数据 非 POD 结构类型的成员, 非 POD 联合(或此类类型的数组) 或参考,并且没有用户定义的 复制赋值运算符否 用户定义的析构函数。同样,一个 POD-union 是一个聚合联合,它 没有类型的非静态数据成员 非 POD 结构,非 POD 联合(或 此类类型的数组)或引用,以及 没有用户定义的副本分配 运算符没有用户定义 析构函数。 POD 类是一个类 这是一个 POD 结构或一个 POD 联合。

由此可见,POD 类/结构/联合虽然不能有用户定义的赋值操作符用户定义的析构函数


不过,还有其他类型的 POD。第 3.9/10 节说,

算术类型 (3.9.1), 枚举类型、指针类型和 指向成员类型 (3.9.2) 的指针,以及 这些类型的 cv 限定版本 (3.9.3) 统称为标量 类型。标量类型、POD 结构类型、 POD 联合类型(第 9 条),数组 此类类型和 cv 限定版本 这些类型 (3.9.3) 是 统称为 POD 类型

阅读此常见问题解答:What is a "POD type"?

【讨论】:

    【解决方案2】:

    A类是POD,可以这样初始化

    对不起,那是错误的。因为b 是私有的,所以该类不是 POD。

    但是 Clang 假定 A 是非聚合类型。为什么我不能有这样的构造函数?还是我应该做点别的?

    这是当前存在的 C++ 的限制。 C++0x 将不再有这个限制。虽然在 C++0x 中您的类型也不是 POD,但您的初始化将起作用(假设您创建了该构造函数 public)。

    (另外,我认为你在这里使用的一个更好的术语是“聚合”。使用{ ... } 的要求是你的类是一个聚合。它不一定是一个POD)。

    【讨论】:

    • 哦,谢谢。使用class 而不是struct 是我的错误。对不起。我不在乎默认访问。我更新了我的问题。对聚合但非 POD 类型的评论本身很有帮助:)
    【解决方案3】:

    其他答案很好地描述了 POD 规则。如果您想获得与 POD 的构造函数类似的初始化样式,可以使用 make_ 样式函数,例如:

    struct A
    {
        int i_;
    };
    
    A make_A(int i = 0) 
    {
        A a = { i }; 
        return a; 
    }
    

    现在您可以获得初始化的 POD 实例,例如:

    A a = make_A();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-10
      • 2017-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-21
      相关资源
      最近更新 更多