假设我有一个带有一些成员变量且没有虚函数的基类:
class Base {
int member;
};
Run Code Online (Sandbox Code Playgroud)
以及从非虚拟方式派生Base并且没有新成员变量的派生类,再次没有虚函数:
class Derived : Base {
};
Run Code Online (Sandbox Code Playgroud)
显然sizeof(Derived)不能小于sizeof(Base).
被sizeof(Derived)要求等于sizeof(Base)?
在c/c ++中(我假设它们在这方面是相同的),如果我有以下内容:
struct S {
T a;
.
.
.
} s;
Run Code Online (Sandbox Code Playgroud)
以下是否保证是真的?
(void*)&s == (void*)&s.a;
Run Code Online (Sandbox Code Playgroud)
或者换句话说,是否有任何保证在第一个成员之前没有填充?
在今天早些时候提出的问题以及大量相似的主题问题之后,我在这里从标准的角度询问这个问题.
struct Base
{
int member;
};
struct Derived : Base
{
int another_member;
};
int main()
{
Base* p = new Derived[10]; // (1)
p[1].member = 42; // (2)
delete[] p; // (3)
}
Run Code Online (Sandbox Code Playgroud)
根据标准(1)是格式良好的,因为Dervied*(这是new-expression的结果)可以隐式转换为Base*(C++ 11 draft,§4.10/ 3):
类型为"指向cv D的指针"的prvalue ,其中D是类类型,可以转换为类型为"指向cv B的指针"的prvalue ,其中B是D的基类(子句10).如果B是D不可访问(第11条)或模糊(10.2)基类,需要这种转换的程序是不正确的.转换的结果是指向派生类对象的基类子对象的指针.空指针值将转换为目标类型的空指针值.
(3) 由于§5.3.5/ 3导致未定义的行为:
在第一个备选(删除对象)中,如果要删除的对象的静态类型与其动态类型不同,则静态类型应为要删除的对象的动态类型的基类,静态类型应具有虚拟析构函数或行为未定义.在第二个备选(删除数组)中,如果要删除的对象的动态类型与其静态类型不同,则行为未定义.
(2)根据标准是合法的还是会导致形成不良的程序或不明确的行为?
编辑:更好的措辞