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
私有继承将类更改为NOT标准布局兼容。
我不确定这是否是一个g ++错误(我正在使用g ++ 4.6.1),或者标准被某种方式违反了。
答案 0 :(得分:4)
我认为这里有一个混乱:
这两个概念是正交的。
<强>更新强>
以下显示与boost::noncopyable
:
#include <iostream>
struct foo {};
struct B : foo { int data; };
struct D : foo { B data; };
int main() {
D d;
std::cout << (char*)(&d.data) - (char*)(&d) << "\n";
}
结果为4
。
我相信这是因为:
实际上,实验表明在int a;
之前在D
中引入data
不会增加其大小。我认为B
继承自foo
这一事实意味着data
(第一个非静态数据成员)被认为是与foo
相同的类型(基类D
)。
这会导致歧义:如果编译器没有引入此填充,foo* f = &d
将具有与foo* g = &b.data;
相同的地址。
答案 1 :(得分:0)
要使您的课程不可复制,您需要做两件事:
您不需要继承某些boost类就可以获得该行为。
我可以补充一下,谁关心一些花哨的'标准布局'的想法。编程你需要的东西,不要屈服于这种极端空间理论。