gpt4 book ai didi

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

转载 作者:搜寻专家 更新时间:2023-10-31 01:16:29 25 4
gpt4 key购买 nike

C++11,§9/7:

A standard-layout class is a class that:

  • has no non-static data members of type non-standard-layout class (or array of such types) or reference,
  • has no virtual functions and no virtual base classes,
  • has the same access control for all non-static data members,
  • has no non-standard-layout base classes,
  • either has no non-static data members in the most derived class and at most one base class with non-static data members, or has no base classes with non-static data members, and
  • has no base classes of the same type as the first non-static data member.

那么,有没有办法让标准布局的类不可复制?如果是,如何?

从 boost::noncopyable 私有(private)继承将不起作用,因为它使复制构造函数私有(private)(因此不是标准布局)。 boost::noncopyable 的实现是这样的:

  class noncopyable
{
protected:
noncopyable() {}
~noncopyable() {}
private: // emphasize the following members are private
noncopyable( const noncopyable& );
const noncopyable& operator=( const noncopyable& );
};

因为私有(private)部分,它不是一个标准的布局类。我还注意到私有(private)继承是否违反了任何标准布局规则。


#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 私有(private)继承会将类更改为不符合标准布局。我不确定这是一个 g++ 错误(我使用的是 g++ 4.6.1),还是以某种方式违反了标准。

最佳答案

我认为这里有一个混淆:

  • 标准布局属性受属性影响(且仅受属性影响)
  • 可复制属性受方法影响(它们的存在、不存在和可访问性)

这两个概念是正交的。

更新:

下面显示了与 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; 不会增加其大小。我认为 B 继承自 foo 的事实意味着 data (第一个非静态数据成员)被认为是与foo(D 的基类)。

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

关于c++ - 标准布局和不可复制的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9077949/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com