我试图实现的是跟踪我们创建的从基类继承的对象的类型。如果一个类继承自基类,但没有在对象中实例化,那么我对跟踪它就不太感兴趣了(这个条件可以包含,也可以不包括,这取决于实现是否简单)
虚构的例子:
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类型指针吗?
至于异构容器,我认为可以使用链接。
发布于 2019-03-14 16:22:46
或多或少,我有个地方像这样工作:
#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;
}产出如下:
Registered type 0 label ClassA
Registered type 1 label ClassB其主要思想是在构造中使用CRTP和静态初始化,每种类型只注册一次。它在linux中没有问题,在windows编译器上,静态BaseClass ID在每个DLL上都是新的,所以您需要调优一些以便在外部库中使用。
使用这种方法,您不需要任何外部库,并且可以在没有rtti的情况下编译。
对于继承,可以创建一个新类:
template<typename Current, typename Base>
class Mix : public MyClass<Current>, public Base {};因此,如果将“类型C”作为当前类型(CRTP)和作为基类的类型A传递,则可以工作。
class C : public Mix<C, A> {
public:
C() {
}
static const char *GetType() {
return "ClassC";
}
};使用这种方法,如果您以前注册了"A“,它将不再注册,如果您没有"A”,它将注册在"C“之后。
https://stackoverflow.com/questions/55161026
复制相似问题