为什么在定义Q_DECLARE_PRIVATE宏时在d_fun()实现中使用reinterpret_cast

Why reinterpret_cast is used in the implementation d_fun() while defining Q_DECLARE_PRIVATE macro

本文关键字:实现 cast reinterpret DECLARE 定义 PRIVATE 为什么 fun      更新时间:2023-10-16

Qt类在公共类中有一个Q_DECLARE_PRIVATE宏。宏的内容是:

#define Q_DECLARE_PRIVATE(Class)
    inline Class##Private* d_func() {
        return reinterpret_cast<Class##Private*>(qGetPtrHelper(d_ptr));
    }
    inline const Class##Private d_func() const {
        return reinterpret_cast<const Class##Private *>(qGetPtrHelper(d_ptr));
    }
    friend class Class##Private;

在这里,根据我的理解,Class##Private将是d_ptr类的父类,那么为什么使用reinterpret_cast而不是dynamic_cast呢?

原因如下:

  1. 在Qt源代码中不支持dynamic_cast,因为Qt可以在关闭RTTI的情况下构建。

    dynamic_cast<字符串在非测试,非第三方Qt 5.7.0源代码中出现了大约十几个位置,其中大多数本质上是错误/遗漏。

  2. 该宏用于前定义Class##Private的头文件中。static_cast不能工作,因为编译器不知道Class##Private是从d_ptr的指向类型派生出来的。

  3. 如果Class##Private不是前向定义的,那么正确的类型转换应该是static_castdynamic_cast将是一个过早的悲观化,因为宏是在编译时知道d_ptr的指向类型的地方使用的,尽管不是在头文件中。

有关Q_DECLARE_PRIVATE的更多详细信息,请参见如何使用Qt's PIMPL习语?

因为dynamic_cast要求类至少有一个virtual方法(它需要是多态的)。仅仅继承类是不足以让dynamic_cast成功的。