首页 文章

标准布局和不可复制的属性

提问于
浏览
2

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 bug(我正在使用g 4.6.1),或者标准是以某种方式被违反的 .

2 回答

  • 4

    我认为这里有一个混乱:

    • 标准布局属性受属性(仅属性)的影响

    • 可复制属性受方法影响(它们的存在,缺失和可访问性)

    这两个概念是正交的 .

    UPDATE:

    以下显示与 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 .

    我相信这是因为:

    • 没有与第一个非静态数据成员相同类型的基类 .

    实际上,实验表明在 data 之前在 D 中引入 int a; 并不会增加其大小 . 我认为 Bfoo 继承的事实意味着 data (第一个非静态数据成员)被认为是与 fooD 的基类)相同的类型 .

    这会导致歧义:如果编译器没有引入此填充, foo* f = &d 将具有与 foo* g = &b.data; 相同的地址 .

  • 0

    要使类不可复制,您需要做两件事:

    • 将复制构造函数设为私有 .

    • 将赋值运算符设为私有 . (它被赋予与类本身相同类型的另一种类型) .

    你不需要继承一些boost类来获得那种行为 .

    我可以补充说,谁在乎一些花哨的“标准布局”的想法 . 编程你需要的东西,不要屈服于这种极端空间理论 .

相关问题