【发布时间】:2012-02-23 01:52:28
【问题描述】:
C++11,第 9/7 节:
一个标准布局类是一个类:
- 没有非标准布局类(或此类类型的数组)或引用类型的非静态数据成员,
- 没有虚函数,也没有虚基类,
- 对所有非静态数据成员具有相同的访问控制,
- 没有非标准布局基类,
- 要么在派生最多的类中没有非静态数据成员,并且最多有一个具有非静态数据成员的基类,要么没有具有非静态数据成员的基类,并且
- 没有与第一个非静态数据成员相同类型的基类。
那么,有没有办法使具有标准布局的类不可复制?如果是,怎么做?
从 boost::noncopyable 私有继承将不起作用,因为它使复制构造函数私有(因此不是标准布局)。 boost::noncopyable 的实现是这样的:
class noncopyable
{
protected:
noncopyable() {}
~noncopyable() {}
private: // emphasize the following members are private
noncopyable( const noncopyable& );
const noncopyable& operator=( const noncopyable& );
};
由于私有部分,它不是标准的布局类。我还注意到私有继承是否违反任何标准布局规则。
#include <boost/noncopyable.hpp>
#include <iostream>
const int N = 50;
struct A
{
int data[N];
};
struct B : private boost::noncopyable
{
int data[N];
};
struct C
{
A data[10];
};
struct D : private boost::noncopyable
{
B data[10];
};
int main() {
std::cout<<sizeof(A)<<std::endl;
std::cout<<sizeof(B)<<std::endl;
std::cout<<sizeof(C)<<std::endl;
std::cout<<sizeof(D)<<std::endl;
}
输出是:
200
200
2000
2004
上面的例子表明,从boost::noncopyable 私有继承会将类更改为不符合标准布局。
我不确定这是否是一个 g++ 错误(我使用的是 g++ 4.6.1),或者该标准被某种方式违反了。
【问题讨论】:
-
你为什么认为将复制构造函数设为私有会使类不是标准布局?
-
@Mankarse 那么,标准布局类可以有私有复制构造函数吗?
-
函数不是“非静态数据成员”。因此,假设您正确引用了定义,“私人部分”不会使
noncopyable非标准布局。 -
我添加了一个示例,其中从 boost::noncopyable 继承的类包括标准布局类(再次从 boost::noncopyable 继承)不是标准布局类。你能解释一下吗?
-
@VJovic :类型增加的大小与标准布局正交(第 9.2/20 节特别允许)——GCC 只是没有应用空基优化。如果你想检查某个东西是否是标准布局,不要看大小,使用它的类型特征 (
std::is_standard_layout<>)。
标签: c++ c++11 noncopyable standard-layout