首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >跟踪对象类型

跟踪对象类型
EN

Stack Overflow用户
提问于 2019-03-14 11:12:02
回答 3查看 201关注 0票数 1

我试图实现的是跟踪我们创建的从基类继承的对象的类型。如果一个类继承自基类,但没有在对象中实例化,那么我对跟踪它就不太感兴趣了(这个条件可以包含,也可以不包括,这取决于实现是否简单)

虚构的例子:

代码语言:javascript
运行
复制
template <typename T>
class Person
{
public:
    Person() {
        T* x;
        container.push_back(x);
    }
    virtual ~Person() {}
private:
    static heterogeneous_container container;
};

class Employee : public Person <Employee>
{
};

class Employee2 : public Employee
{
};

此外,我希望这个工作的链式继承。当我实例化一个Employee2时,基类Person会在容器中添加一个Employee2类型指针吗?

至于异构容器,我认为可以使用链接

EN

Stack Overflow用户

回答已采纳

发布于 2019-03-14 16:22:46

或多或少,我有个地方像这样工作:

代码语言:javascript
运行
复制
#include <iostream>
#include <functional>
#include <vector>

struct ClassEntry {
    size_t id = 0;
    const char* label;
};

class BaseClass {
public:
protected:

    static void RegisterType(size_t id, const char * label) {
        ClassEntry entry;
        entry.id = id;
        entry.label = label;
        mRegisteredTypes.emplace_back(entry);

        std::cout << "Registered type " << id << " label " << label << std::endl;
    }

    static size_t createId() {
        static size_t id = 0;
        return id++;
    }

    static std::vector<ClassEntry> mRegisteredTypes;
};

std::vector<ClassEntry> BaseClass::mRegisteredTypes;


class OneTimeCall {
public:
    OneTimeCall(std::function<void(void)>&& func)  {
        func();
    }
    virtual ~OneTimeCall() {

    }
};


template<typename T>
class MyClass : public BaseClass {
public:
    MyClass() {
        static OneTimeCall one_time {
            [this]{
                BaseClass::RegisterType(GetId(), T::GetType());
            }
        };


    }
private:

protected:

    static size_t GetId() {
        static size_t id = BaseClass::createId();
        return id;
    }
};


class A : public MyClass<A> {
public:
    A() {

    }

   static const char *GetType() {
        return "ClassA";
   }
};

class B : public MyClass<B> {
public:
    B() {

    }

    static const char *GetType() {
        return "ClassB";
    }
};


int main() {

    A a;
    B b;
    A a2;
    B b2;


    return 0;
}

产出如下:

代码语言:javascript
运行
复制
Registered type 0 label ClassA
Registered type 1 label ClassB

其主要思想是在构造中使用CRTP和静态初始化,每种类型只注册一次。它在linux中没有问题,在windows编译器上,静态BaseClass ID在每个DLL上都是新的,所以您需要调优一些以便在外部库中使用。

使用这种方法,您不需要任何外部库,并且可以在没有rtti的情况下编译。

对于继承,可以创建一个新类:

代码语言:javascript
运行
复制
template<typename Current, typename Base>
class Mix : public MyClass<Current>, public Base {};

因此,如果将“类型C”作为当前类型(CRTP)和作为基类的类型A传递,则可以工作。

代码语言:javascript
运行
复制
class C : public Mix<C, A> {
public:
    C() {

    }

    static const char *GetType() {
        return "ClassC";
    }
};

使用这种方法,如果您以前注册了"A“,它将不再注册,如果您没有"A”,它将注册在"C“之后。

票数 2
EN
查看全部 3 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55161026

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档