大多数C程序员都知道空基类优化是一种技术/习惯用法。空的子类会发生什么?例如
class EmptyBase {
int i;
};
template<typename T>
class Derived : T {
};
std::cout << sizeof(Derived<EmptyBase>); // Is there a standard verdic on this?
与EBO类似,应该有一个EDO声明,由于派生类不提供任何其他成员,也不向其参数化类型引入任何虚拟成员,因此它不需要更多内存。考虑到可能出现类似情况的各种情况(多重继承、单一继承……):
注意:使用从参数化类型派生的类模板是相当典型的。主题是在这种情况下浪费空间
该标准本身不包含“空基类”大小写。相反,它说(参见1.8):
[A] 大多数派生对象应具有非零大小,并应占用一个或多个字节的存储。基类子对象的大小可能为零。
和:
除非一个对象是[…]零大小的基类子对象,否则该对象的地址是它占用的第一个字节的地址。如果一个是另一个的子对象,或者如果至少一个是零大小的基类子对象并且它们是不同的类型,则两个对象[…]可能具有相同的地址;否则,它们应该有不同的地址。
以及(第9条):
类类型的完整对象和成员子对象的大小应为非零。脚注:基类子对象不受此限制。
这从来没有说只有空底座可以接受任何形式的布局更改,并为“挤压”布局留出足够的空间:例如:
struct A {}; struct B : A { int x; }; // "equivalent" to { int }
struct X { int a; }; struct Y : X {}; // "equivalent" to { int }
考虑B b;
和Y y;
。可能b
的地址,A
-b
的子对象的地址(即
唯一不起作用的是这个:
struct S {}; struct T { S s; }; // "equivalent" to { char }
我所说的“等效”
是指最明智、最节省空间的实现。
一个更有趣的案例如下:
struct Foo { int x; char a; }; // { int, char, char[3] }
struct Bar : Foo { short q; }; // { int, char, char, short }
此示例假定大小为(int) == 4
,大小为(短) == 2
。出于对齐原因,我们有大小(Foo) == 8
,但大小(Bar)
也是8
,尽管有更多的数据成员。
该标准的另一个相关部分是9.2/13:
具有相同权限改造(第11条)的(非联合)类的非静态数据成员被分配,以便以后的成员在类对象中具有更高的地址。具有不同权限改造的非静态数据成员的分配顺序是未指定的(11)。实现对齐要求可能会导致两个相邻的成员不能立即相互分配;管理虚函数(10.3)和虚拟基类(10.1)的空间要求也是如此。
最后,9.2/10说标准布局类在开始时没有填充,因此它们的地址等于它们的“初始成员”的地址。由于标准布局要求所有基要么为空,要么派生最多的类本身没有数据成员,这意味着标准布局类必须采用一种“空基”优化,我上面的B
和Y
布局的初始部分实际上是强制性的。
问题内容: 我知道如何使用派生表,但是我仍然可以真正看到使用它们的任何真正优势。 例如,在下面的文章http://techahead.wordpress.com/2007/10/01/sql-derived- tables/中 ,作者试图展示使用派生表的查询优于没有示例的查询的优点,我们要生成一个报告,以显示每个客户在1996年下的订单总数,我们希望该结果集包括所有客户,包括当年未下订单的客户和从
通过 #[derive] 属性,编译器能够提供一些对于 trait 的基本实现。如果需要一个更复杂的业务,这些 trait 仍然可以手动实现。(原文:The compiler is capable of providing basic implementations for some traits via the #[derive] attribute. These traits can stil
但是,如果实用工具类是从Qt类派生的,我会出现链接错误。我认为问题出在Q_OBJECT宏上,如果我不添加它,我就不会得到错误。但是在任何Qt派生类中都必须/建议使用Q_OBJECT宏。 我怎样才能避免这个ISUE?有没有其他方法来拥有一个具有文件作用域的实用程序类? 用于显示错误的简单示例:CMyClass类使用从QWidget派生的实用工具类(名为CUtility)。 错误有: LNK2001:
问题内容: 假设您有这样的查询… 可以将多个人分配给给定任务。该查询的目的是显示每个任务一行,但将分配给该任务的人员显示在单个列中 现在…假设你有正确的指标设置上,和。连接到派生表时,MySQL Optimizer仍将不使用TaskID索引。WTF?!?!? 因此,我的问题是…如何使此查询使用task_assigned_users.TaskID上的索引?临时表是la脚的,所以如果这是唯一的解决方案
问题内容: 我需要帮助,以了解如何在Go中妖魔化一个流程。 如果在命令行上启动此代码,则程序将返回控制权,但仍与cmd连接。关闭cmd将关闭程序。 如何将其与cmd分离?新增: 导致此错误:错误内存指针“恐慌” 问题答案: 我在“ golang-nuts”中询问,发现golang具有链接选项:
数据结构是指若干个数据的连接方式,一个复杂的数据往往是由若干个不同类型数据形成的结构。派生类型是指用户利用FORTRAN系统内部类型,如数值型、逻辑型、字符型等自行设计出一个新的数据类型,它们实际上是由内部类型数据形成的某种结构。本章主要目的是学会按复杂数据的客观结构形态,由程序员定义出一种派生类型,再结合上将在后面叙述的模块后,可将该类型必需的操作写成内部子程序,连同派生类型一起写在模块中,供程