有一个类A继承自该类B。但是,该类B不包含任何字段。如果我创建一个元素数组B,但将其用作元素数组A,它会正确吗?
该标准说这仅允许使用类似的类型:
当具有整数类型的表达式被添加到指针或从指针中减去时,结果具有指针操作数的类型。如果表达式 P 指向具有 n 个元素的数组对象 x 的元素 x[i],86 表达式 P + J 和 J + P(其中 J 的值为 j)指向(可能是假设的)元素 x [ i + j ] 如果 0 ≤ i + j ≤ n ;否则,行为未定义。同样,表达式 P - J 指向(可能是假设的)元素 x [ i - j ] 如果 0 ≤ i - j ≤ n ;否则,行为未定义。
旁边描述了类型的相似性,但我无法理解在我的情况下类型是否相似。哪些类型被认为是相似的?
这是一个示例代码:https://ideone.com/ncRepZ https://ideone.com/nMvJ0r
它是否包含未定义的行为?
#include <iostream>
using namespace std;
struct A
{
int x;
A(int x) : x(x) {}
virtual ~A() {}
};
struct B : A
{
B() : A(7) {}
};
int main()
{
A *a = new B[4];
for (size_t q=0; q<4; ++q)
cout << q << ": " << a[q].x << endl;
delete [] a;
return 0;
}
如果仍然不允许这样做,是否足以检查这两种类型的大小是否相等https://ideone.com/iSkJk0
static_assert(sizeof (A) == sizeof (B), "B must have same size as A");
确保如果程序编译,那么它不包含UB?
第二个链接清楚地表明,如果类型在 const 和 volatile 之前都相同,并且将固定大小的数组替换为未知大小的数组,则它们是相似的:
后代和基本类型之间的转换不包括在相似关系中。
所以正式你不能这样做,它将是UB。在实践中,这个 UB 可以以与任何其他违反严格别名规则的行为相同的方式表现出来: