空基类优化从C
回答
关于“区域”定义的哲学论证是不必要的。 “除非是位域,否则大多数派生对象的大小应该不为零......基类子对象的大小可能为零”。
因此,标准很清楚什么对象(以及哪些“存储区域”)可以具有零大小。如果你不同意这个标准,“区域”在英语中意味着什么是一回事,你可以对作者的(与编程无关的)文学技能作出错误的判断。对于这个问题,你可以错过他们的诗歌技巧(14.7.3/7)。但是,这个标准在这里所说的关于类类型对象的大小很清楚。
阅读标准的实用方法是,如果给出两个合理的单词解释,选择一个与标准的同一部分中的另一个句子不直接相抵触的单词。不要选择更贴近您个人喜欢使用的单词,甚至是最常见的用法。
“除非是位域,否则大多数派生对象应该有一个非零大小”似乎与被称为“分配一个没有元素的数组”的new int [0]冲突。这意味着在这种情况下数组实际上* do *包含内部填充吗? – 2010-05-13 12:45:45
我不认为数组是一个派生最多的对象。 1.8/4:“如果一个完整的对象... ...是类类型,它的类型被认为是最派生类......最派生类类型的对象被称为最派生类对象” – 2010-05-13 12:47:48
@Steve它说“大多数派生类类型或非类类型的对象称为最派生对象“。 - 编辑:C++ 03的措辞似乎与FCD措辞不同。 – 2010-05-13 12:50:19
C++不允许大小为零的对象,因为每个对象都必须具有唯一的内存地址。所以,如果您有:
struct empty {};
// ...
empty myempty;
empty* ptr = &myempty;
然后ptr
必须指向一个唯一的内存地址。该标准规定为此目的,对象的最小尺寸为1个字节。类似地,允许分配大小0,并返回一个有效的指针,即使不允许写入该指针(这适用于malloc(0)
,并且new empty
返回指向一个字节的指针,因为sizeof(empty) == 1
)。
如果我从empty
得到像这样:
struct derived : public empty
{
int data;
}
不再有基类empty
占用一个字节的任何一点,因为所有derived
都会有一个唯一的地址,由于data
成员。在这种情况下,引用“基类子对象可能具有零大小”以允许编译器不为empty
使用任何空间,例如sizeof(derived) == 4
。正如标题所述,这只是一种优化,对derived
的empty
部分占用零空间是完全合法的。
实际上'sizeof(空)'被允许更大,并且大多数编译器至少会使它的机器字宽。 – 2010-05-13 13:18:53
“每个对象都必须具有唯一的内存地址” - 尽管标准中的表述不正确,但每个对象都不需要具有唯一的内存地址。一个对象可以在其开始时与子对象具有相同的地址,和/或基类子对象。应该说每个_complete_对象都必须有一个唯一的地址。 – davmac 2016-06-04 21:49:54
C++标准1.8.5状态: -
除非它是一个位字段(9.6),一个最 派生对象应具有非零 尺寸,并应占据一个或多个 存储字节。 基类 子对象可能具有零大小。一个可以复制的对象 或 标准布局类型(3。9) 占用连续的存储字节。
因此,该标准允许没有数据成员(并且没有虚拟)的基类与另一个具有不同类型的子对象共享相同的地址。您可以玩像空基类大小...
struct a{};
struct a1{};
struct b : public a, public a1{char c;};
int main()
{
std::cout << sizeof(b) << "\n";
std::cout << sizeof(b::a);
}
Which outputs (ignoring padding)...
1
1
now try:
struct a{};
struct b : public a {a ax;};
int main()
{
std::cout << sizeof(b) << "\n";
std::cout << sizeof(b::a);
}
and the output is ...
2
1
因为一个(作为基础和作为成员)的两个实例必须有不同的地址。
BTW:“b :: a”是另一种说“a”的方式。范围访问操作符的存在不会请求“类型a的b的基类子对象”。 5.3.3/2
说: - 将sizeof应用于基类子对象时,结果为该对象的类型为的大小。
- 1. 空基类优化
- 2. 空基优化MSVC
- 3. 通用基类打破元组的空基类优化
- 4. C类优化
- 5. C#空值检查优化
- 6. C++优化/优化
- 7. 优化类结构在C++
- 8. 是std :: tuple需要使用空基类优化吗?
- 9. 为什么空基类优化不起作用?
- 10. C# - 从基类
- 11. 是否优化了空块? C#
- 12. 不C#编译器优化空语句
- 13. 在C#中优化空方法调用
- 14. JPA/Hibernate空值优化查询优化
- 15. 从C++到C#//结构内存优化
- 16. C++从virtal基类
- 17. Objective-C优化
- 18. C++优化
- 19. c#Webcrawler优化
- 20. C++优化
- 21. C++矩阵/位图类的优化
- 22. 优化数据类型MONGO(C#)
- 23. C++自定义类型矢量优化
- 24. C++ Builder 10.2基于函数的优化状态“未知属性”优化“忽略”
- 25. 从派生类到基类的C++成员初始化
- 26. 基于“优化技巧”
- 27. 基本队列优化
- 28. 任何Javascript优化基准?
- 29. 优化从sympy
- 30. C++的reinterpret_cast优化
为什么你认为一个存储区域的大小不能为零?显然它可以:) – 2010-05-13 12:24:36
调用malloc(0)。 – bmargulies 2010-05-13 12:27:48
@bmargulies'malloc'在C语言中特别措辞,因此它不需要创建一个零大小的对象:“如果请求的空间大小为零,则行为是实现定义的:或者返回空指针,或者行为就好像大小是非零值“ – 2010-05-13 12:37:50