动态类型信息(Dynamic Type Info),下称DTI。

基本使用

#include <iostream>
#include <string>
/////////////////////////////////////
//H文件

/// @brief 动态类型信息
class DTI
{
public:
    DTI() = default;
    DTI(const std::string &name, DTI *parent)
        : _name(name), _parent(parent) {};
    ~DTI() = default;

    /// @brief 判断当前类是否是目标类型的子类
    /// @param pType 目标类型
    /// @return 是否是目标类型的子类
    bool IsA(DTI* pType);

// getters and setters
public:
    inline const std::string &getName() const { return this->_name; }
    inline const DTI *getParent() const { return this->_parent; }

    inline void setName(const std::string &name) { this->_name = name; }
    inline void setParent(DTI *parent) { this->_parent = parent; }

private:
    /// @brief 名称
    std::string _name;
    /// @brief 父类信息
    DTI *_parent{nullptr};
};

/// @brief 定义类型信息
#define EXPORT_TYPE \
public:             \
    static DTI Type;

/////////////////////////////////////
//CPP文件

bool DTI::IsA(DTI *pType)
{
    const DTI* current = this;
    while (current != nullptr)
    {
        if(current == pType)
            return true;
        else
            current = current->getParent();
    }
    return false;
}

////////////////////////////////////
//USE使用时

class CRootClass
{
    EXPORT_TYPE
public:
    CRootClass() = default;
    ~CRootClass() = default;
    /// @brief 如果存在频繁使用强制类型转换的时候,可以在基类实现一个安全的类型转换接口
    /// @brief 安全的类型转换
    /// @param pCastToType 目标类型
    /// @return 转换后的指针,如果转换失败,返回nullptr
    void* SafeCast(DTI* pCastToType);

    /// @brief 名称 用于SafeCast示例
    std::string name{"CRootClass"};
};

DTI CRootClass::Type{"CRootClass", nullptr};
void *CRootClass::SafeCast(DTI *pCastToType)
{
    if (this->Type.IsA(pCastToType))
        return this;
    return nullptr;
}

class CChildClass : public CRootClass
{
    EXPORT_TYPE
public:
    CChildClass() = default;
    ~CChildClass() = default;

    /// @brief 名称 用于SafeCast示例
    std::string name{"CChildClass"};
};

DTI CChildClass::Type{"CChildClass", &CRootClass::Type};

int main()
{
    // 示例1 子类直接查询父类名称
    std::cout << "Type name: " << CChildClass::Type.getName() << std::endl;
    std::cout << " Parent type name: "
              << CChildClass::Type.getParent()->getName() << std::endl;

    // 示例2 子类查询是否属于某个父类
    CChildClass child;
    if(child.Type.IsA(&CRootClass::Type))
    {
        std::cout << "child is a CRootClass" << std::endl;
    }
    // 示例3 子类强制转换为父类 若转换失败,返回nullptr
    auto cr = (CRootClass *)child.SafeCast(&CRootClass::Type);
    std::cout << cr->name << std::endl;

    return 0;
}

在持久化数据时的运用

待补充