C ++ POD类型不能有任何构造函数吗?

时间:2011-03-26 13:48:40

标签: c++ constructor pod

我有一个类和一个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关于混淆:)

3 个答案:

答案 0 :(得分:18)

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

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

  

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

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

  

[....] POD-struct是聚合类,没有非静态数据   非POD结构类型的成员,   非POD联合(或此类型的数组)   或引用,并且没有用户定义   复制分配运算符否   用户定义的析构函数。同样,a   POD-union是一个聚合联盟   没有类型的非静态数据成员   非POD结构,非POD结合(或   这类类型的数组)或引用,和   没有用户定义的副本分配   运营商没有用户定义   析即可。 POD类是一个类   这是一个POD结构或一个   POD联合

从这一点来看,它也清楚POD类/ struct / union虽然也不能有用户定义的赋值运算符用户定义的析构函数


然而,还有其他类型的POD。 §3.9/ 10节说,

  

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

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

答案 1 :(得分:5)

  

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

抱歉,这是错误的。由于b是私有的,因此该类不是POD。

  

但Clang将A视为非聚合类型。为什么我不能有这样的构造函数?或者我应该做些什么?

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

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

答案 2 :(得分:2)

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

struct A
{
    int i_;
};

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

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

A a = make_A();