C++将一个指针分配给另一个指针时执行的类型检查

C++ typechecks performed when assigning one pointer to another

本文关键字:指针 另一个 执行 检查 类型 分配 C++ 一个      更新时间:2023-10-16

我想知道编译器在下面所做的类型检查的扩展

class Parent{
};
class Child : public Parent{
};
class Unrelated{
};
main(){
Parent* p = new Child() // OK. But type of p is still Parent* and not Child*
Unrelatead* u = new Child() // Not OK. Child* is not Unrelated*.
}

因此,在第一个赋值中,p 现在指向 Child 中的"Parent"对象,而第二个赋值根本不允许,尽管最终 p 和 you 都将保留内存地址。

编译器在这些赋值期间执行的确切检查是什么,编译器在编译的哪个部分强制执行这些检查?

第一个赋值是可以的,因为编译器会将基类的所有内存排列在派生类的内存前面。 因此,您可以向上转换指针,因为基类的所有字段仍将指向。

第二个分配是不行的,因为Child不会从Unrelated继承,因此它们的内存布局可能不同。 编译器跟踪这些类层次结构。 这些检查仅在编译时进行。

请注意,向上投射指针可能很危险。 如果类不是虚拟的,则delete p不会调用派生类的析构函数,从而导致潜在的内存泄漏。 如果您决定向上广播并delete指针,请确保您正在为虚拟课程执行此操作。

编译器允许分配数据指针:

  1. 当两者都是指向同一类型的指针,或者目标指针是指向更严格的const/volatile限定类型的指针时,例如T*T const volatile*.
  2. 指向派生类的指针
  3. 可以分配给指向具有类似或更严格的const/volatile限定的可访问基类的指针,例如Derived*Base const*.
  4. 任何指向具有类似或更严格的const/volatile资格void*的数据指针,例如T const*void const*.

Parent* p = new Child();编译,因为它是案例 2。

Unrelatead* u = new Child();无法编译,因为它不是上述情况。要使不相关的数据指针之间的分配正常工作,需要reinterpret_cast<>