gpt4 book ai didi

c++ - 是否有可能知道派生类的所有名称?

转载 作者:太空狗 更新时间:2023-10-29 22:57:35 24 4
gpt4 key购买 nike

假设我们有一个基类和一堆派生类。是否有任何方式或机制以编程方式知道所有派生类名称?

也许反射是个好主意,但它在 C++ 上不可用。我想会有某种模板可以在编译期间完成这项工作。

class Base{
public:
virtual void print(){
// This function should print all the names of derived class.
}
virtual Base* getInstance(string class_name){
// This function should return an instance related to the class name.
}
};

class Derived_1 : public Base{ // Suppose we have 100 Derived_X classes,
// so we don't want to add its name to a list manually.
};

int main(){
Base base;
base.print(); // This should print the name of all the derived class.
base.getInstance("Derived_1"); // This should return an instance of Derived_1
return 0;
}

最佳答案

此解决方案基于这样一个事实,即您似乎实际上是在寻找工厂。它使用一个小宏来简化类注册,希望您不要关心它。

factory.h

#ifndef __FACTORY_H__
#define __FACTORY_H__

#include <map>
#include <functional>
#include <string>
#include <iostream>

template<class B>
class Factory {
std::map<std::string, std::function<B*()>> s_creators;

public:
static Factory<B>& getInstance() {
static Factory<B> s_instance;
return s_instance;
}

template<class T>
void registerClass(const std::string& name) {
s_creators.insert({name, []() -> B* { return new T(); }});
}

B* create(const std::string& name) {
const auto it = s_creators.find(name);
if (it == s_creators.end()) return nullptr; // not a derived class
return (it->second)();
}

void printRegisteredClasses() {
for (const auto &creator : s_creators) {
std::cout << creator.first << '\n';
}
}
};
#define FACTORY(Class) Factory<Class>::getInstance()

template<class B, class T>
class Creator {
public:
explicit Creator(const std::string& name) {
FACTORY(B).registerClass<T>(name);
}
};

#define REGISTER(base_class, derived_class) \
Creator<base_class, derived_class> s_##derived_class##Creator(#derived_class);

#endif

example.cpp

#include "factory.h"
#include <memory>

class Base {
public:
virtual void printName() const { std::cout << "Base\n"; }
};

class Derived1 : public Base {
public:
virtual void printName() const override { std::cout << "Derived1\n"; }
};
REGISTER(Base, Derived1);

class Derived2 : public Base {
public:
virtual void printName() const override { std::cout << "Derived2\n"; }
};
REGISTER(Base, Derived2);

int main() {
std::cout << "Registered classes:" << std::endl;
FACTORY(Base).printRegisteredClasses();

std::cout << "---" << std::endl;
std::unique_ptr<Base> derived1(FACTORY(Base).create("Derived1"));
derived1->printName();

return 0;
}

注意:需要 C++11。

关于c++ - 是否有可能知道派生类的所有名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43653962/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com