09 January 2023

C++ 核心指南目录

“Never assign a pointer to an array of derived class objects to a pointer to its base”

理由

对基类指针的下标访问,会访问到无效对象,甚至可能是内存数据破坏。

例子

struct B { int x; };
struct D : B { int y; };

void use(B* b) { cout << b[0].x << " " << b[1].x << " " << b[2].x;};

int main()
{
    D a[] = {{1, 2}, {3, 4}, {5, 6}};
    cout << a[0].x << " " << a[0].y << endl;
    B* p = a;     // bad: a decays to &a[0] which is converted to a B*
    p[1].x = 7;   // overwrite a[0].y
    cout << a[0].x << " " << a[0].y << endl;
    use(a);       // bad: a decays to &a[0] which is converted to a B*
}
1 2
1 7
1 7 3

上面运行结果,第二行 a[0].y 被迁移行语句给覆盖成了 7。use 函数打印出 a[0] 的 x 与 y,以及 a[1] 的 x。

强化

  • 标记所有派生类数组指针赋值给基类指针的情况
  • 以 span 而非指针的方式传递数组,装入 span 的时候不要进行派生类到基类转换