派生对象数组到基础对象数组
Array of derived objects to array of base objects
有多个问题与此问题非常相似,不同之处在于存在sizeof(Base) != sizeof(Derived)
。由于明显的原因,这将不起作用(指针上应用的下标运算符是相对于指针大小的,而不是实际的反遍历类型)。然而,我想知道这个代码是否正确:
struct Base
{
int Data;
};
struct Derived : public Base
{
};
int main()
{
static_assert(sizeof(Base) == sizeof(Derived), "Sizes are not equal");
Derived Data[10];
Base* Ptr = Data;
Ptr[3].Data = 5;
}
显然,由于大小相等,Ptr[3]
将不再访问任何半撕裂的Base
实例,但代码仍然正确吗?
是的,这是正确的(在定义明确的意义上,不一定是理智的),因为这两个类是布局兼容的-它们是具有相同非静态数据成员的标准布局结构。
不过它非常脆弱;对类的微小更改可能会破坏兼容性并产生未定义的行为。
假设我们有一个函数接收Derived
double foo(Derived d);
现在考虑一下代码的一个细微变化:
Derived Data[10];
Base* Ptr = Data;
Base myB;
Ptr[3] = myB;
本质上,我们已经将一个Base
对象放入Data
数组中。然后我们打电话给
foo(Data[3]);
瞧,我们诱骗foo
接收Base
这就是不应将Derived的数组视为Base的数组的原因。这不仅仅是尺寸的问题。
让我们考虑以下行:
Derived Data[10];
Base* Ptr = Data;
CCD_ 9保存数组的第一个元素的地址。因此,它是一个类型为Derived*
的指针。存在从Derived*
到Base*
的静态强制转换。这意味着代码是正确的。
这是正确的,但通常不会这样做,因为当派生类的指针指向基对象时,数据可能会损坏。
相关文章:
- 将对象数组的引用传递给函数
- 如何使用Visual Studio 2017在C++中为参数化对象数组使用唯一指针
- 在c++中尝试对对象数组进行排序时,出现std:bad_alloc错误
- 类对象数组的问题会导致崩溃
- Arduino C++在构造函数中用参数声明对象数组
- 使用对象数组对 SFML 进行动画处理
- C++ 对象数组堆栈溢出
- 如何将对象数组作为参数传递给模板
- 使用向量初始化参数化构造函数的对象数组
- 如何初始化对象数组?
- C++创建对象数组
- 在对象数组中搜索字符串并返回相应值的函数
- 有没有办法使用该类的构造函数初始化另一个类的私有部分内的对象数组?
- 如何在运行时在对象数组中动态追加新对象C++并打印它们
- 为什么我在声明对象数组时不能使用 -> 运算符?
- 编译时生成应在构造函数中创建的非 constexpr 对象数组
- 使用 C++ 创建对象数组
- 对象数组打印空白字符串
- 重载运算符 [] 用于从对象数组中给出特定索引
- 如何在 C++ 中使用提升属性树从 JSON 文件中读取对象数组