具有所有私有成员的类可以是 POD 类吗?
Posted
技术标签:
【中文标题】具有所有私有成员的类可以是 POD 类吗?【英文标题】:Can a class with all private members be a POD class? 【发布时间】:2011-06-13 08:43:47 【问题描述】:我之前听说 POD 类型不能有私有数据——但根据 C++0x 草案,我的要求比较宽松(强调我的):
对所有非静态数据成员具有相同的访问控制(第 11 条)
这似乎表明私有数据是可以的,只要它都是私有的。我没有 C++03 的副本可以检查...
那么,WindowsApi::Uuid
会是一个 POD 类吗?
namespace WindowsApi
class Uuid
union
::UUID asUuid; //Win32's UUID struct
unsigned __int64 asInt64s[2];
unsigned __int32 asInt32s[4];
;
public:
Uuid()
Uuid(::UUID sourceStructure) : asUuid(sourceStructure)
operator ::UUID() return asUuid;
;
【问题讨论】:
【参考方案1】:我之前听说过 POD 类型不能有私有数据
在 C++03 中,POD 类型不能有私有数据(参见 AndreyT 的回答)。
但是 POD 的定义在 C++0x 中已经改变(参见9/10
)。
根据n3225
POD 结构是一个既是普通类又是标准布局类的类,并且没有非 POD 结构、非 POD 联合(或此类类型的数组)。 ... ...
POD 类是一个 POD 结构或 POD 联合的类。
意思是
struct demo
private:
int a, b;
;
在 C++0x 中是 POD,因为 demo
既是平凡又是标准布局。
标准布局的定义在9/7
部分
标准布局类是这样的类:
没有非标准布局类(或此类类型的数组)或引用类型的非静态数据成员, 没有虚函数 (10.3) 和虚基类 (10.1), 对所有非静态数据成员具有相同的访问控制(第 11 条), 没有非标准布局基类, 在最派生类和最多一个基类中没有非静态数据成员 非静态数据成员,或没有具有非静态数据成员的基类,并且 没有与第一个非静态数据成员相同类型的基类。11
.
那么,WindowsApi::Uuid 会是一个 POD 类吗?
不! WindowsApi::Uuid
既不是 C++03 中的 POD,也不是 C++0x 中的 POD。普通类是具有普通默认构造函数 (12.1) 并且可以普通复制的类。 WindowsApi::Uuid
有一个重要的默认构造函数。
那么这个规则在 C++0x 中放宽了吗?
是的! (考虑第 11 条)
还可以查看FAQ entry on Aggregates and PODs
【讨论】:
那么“琐碎”的定义是什么? :) @bdonlan : 普通类是具有普通默认构造函数 (12.1) 并且可轻松复制的类。 @Parasoon:哎呀..忘记了默认的析构函数:P 不是那个意思。 +1【参考方案2】:C++03 仍然不允许在 POD 类中使用非静态私有或受保护数据。此要求在聚合
的定义中指定聚合是一个数组或类(第 9 条),没有用户声明的构造函数 (12.1),没有私有或受保护的非静态数据成员(第 11 条),没有基类 (第 10 条),并且没有虚函数(10.3)。
并且 POD 类必须首先是一个聚合。
【讨论】:
那么这个规则在 C++0x 中放宽了? (我在 C++0x 草案中没有看到任何关于 POD 类型定义的聚合)【参考方案3】:根据我的 n3225 C++0x 草稿,WindowsApi::Uuid
是一个 POD 类。
从第 219 页开始: POD 结构是一个既是普通类又是标准布局类的类,并且没有非 POD 结构、非 POD 联合(或此类类型的数组)类型的非静态数据成员。
平凡类是具有平凡默认构造函数并且可以平凡复制的类:
一般可复制的类是这样的类:
没有重要的复制构造函数 (12.8), 没有重要的移动构造函数 (12.8), 没有重要的复制赋值运算符(13.5.3、12.8), 没有重要的移动赋值运算符(13.5.3、12.8),并且 有一个简单的析构函数 (12.4)。标准布局类是这样的类:
没有非标准布局类(或此类类型的数组)或引用类型的非静态数据成员, 没有虚函数 (10.3) 和虚基类 (10.1), 对所有非静态数据成员具有相同的访问控制(第 11 条), 没有非标准布局基类, 要么在最派生类中没有非静态数据成员,并且最多有一个具有非静态数据成员的基类,要么没有具有非静态数据成员的基类,并且 没有与第一个非静态数据成员相同类型的基类。由于WindowsApi
不违反任何这些约束,它将是 C++0x 下的有效 POD 类。正如 AndreyT 所提到的,这是比 C++03 更慷慨的措辞。
【讨论】:
我在该类中看不到任何用户定义的复制构造函数。构造函数和转换操作符组合成一个拷贝构造函数吗? 它没有用户定义的复制构造函数。::WindowsApi::Uuid
是我的班级,::UUID
是 Windows 定义的班级。 (注意 Caps 的区别)
@Billy :虽然你有一个不平凡的默认构造函数。 WindowsApi::Uuid
不是 POD。
@Billy:谢谢!不知何故,我将 ::UUID 误读为类的名称。我会更新的。 @Prasoon:默认构造函数是可以在没有任何参数的情况下调用的构造函数。唯一定义的构造函数不是一个。以上是关于具有所有私有成员的类可以是 POD 类吗?的主要内容,如果未能解决你的问题,请参考以下文章