2

我有一个由继承定义的 C++ 类层次结构,我在其中存储了这个层次结构的描述,以后可以用于自省。我想知道是否有比我目前的方式更有效或更清洁的方式来定义它。这是我的代码的精简版

// in header file (hpp)
struct Type
{
    Type( const string& n, const Type* p = nullptr ) : name(n), parent(p) {}
    const string name;
    const Type* parent;
};

class Base
{
public:
    static const Type m_type;
    virtual const Type& type() const { return m_type; } 
};

class Derived : public Base
{
public:
    static const Type m_type;
    const Type& type() const { return m_type; }
};

// in implementation file (cpp)
const Type Base::m_type( "Base" );
const Type Derived::m_type( "Derived", &Base::m_type );
4

1 回答 1

2

不一定更有效,但请考虑您是否真的需要一个公共基类。另一种方法使用全局类型信息注册表。然后通过TypeInfo::get(my_variable)or来查询类型的类型信息TypeInfo::get(typeid(my_type))

这样做的好处是它也适用于现有类型,只需将其添加到此类型信息注册表中即可。

在内部,注册表将使用从std::type_infoType或类似的映射。以下是概念证明。不幸的是,代码不能在 clang 或 GCC 上编译。根据错误消息,我怀疑是一个错误,但我也可能是错的……</p>

struct Type {
    std::string name;
    std::vector<Type*> parents;
    // TODO Extend by fully-qualified name (namespace) etc.

    template <typename... T>
    Type(std::string&& name, T*... parents)
        : name(name), parents{parents...} { }
};

struct TypeInfo {
    template <typename T>
    static Type const& get(T const&) { return get(typeid(T)); }

    template <typename T>
    static Type const& get() { return get(typeid(T)); }

    static Type const& get(std::type_info const& info) {
        auto i = types.find(info);
        if (i == types.end())
            throw unknown_type_error(info.name());

        return i->second;
    }

    template <typename T>
    static void register_type(Type&& type) {
        types.insert(std::make_pair(typeid(T), type));
    }

    typedef std::unordered_map<std::type_info, Type> type_dir_t;
    static type_dir_t types;
};

完整代码可在 github 上作为 gist 获得

在 C++ 中,通常不赞成为逻辑上不相关的类使用公共基类,尽管可以说这类似于 CRTP / mixins,其中鼓励使用公共基。所以我想说,如果你不关心现有类型,这种方法不一定有什么问题。

于 2012-05-16T13:10:33.370 回答