gpt4 book ai didi

使用宏的 C++ 动态实例化

转载 作者:行者123 更新时间:2023-11-30 04:56:42 24 4
gpt4 key购买 nike

我试图在 C++ 中实现动态实例化,我的意思是,从类的字符串创建实例。但经过一番挖掘,我发现 C++ 似乎并不原生支持这样的功能。

例如,我有一个名为 Person 的“接口(interface)” ,以及一些具体的实现,如 Worker , Teacher , Programmer等。在 C++ 中,如果我想将所有实现存储到映射中 collection ,我必须写这样的东西:

#include <map>
#include <string>

#include "Worker.hpp"
#include "Teacher.hpp"
#include "Programmer.hpp"
// ...

using namespace std;

int main() {
map<string, Person*> collection;
Worker worker;
Teacher teacher;
Programmer monkey;
// ...

collection[worker->title] = &worker;
collection[teacher->title] = &teacher;
collection[monkey->tittle] = &monkey;
// ...
}

看起来还可以,但我不喜欢每次添加职位时都更改代码中的三个地方。我想做的是这样的:

#include <map>
#include <string>
#include "Worker.hpp"
#include "Teacher.hpp"
#include "Programmer.hpp"
# ...

using namespace std;

int main() {
map<string, Person*> collection;
char titles[][20] = {"Worker", "Teacher", "Programmer"};

for (auto const &Title: titles) {
// this is the magic I would like to have.
Title object;
collection[title] = &object;
}
}

不幸的是,C++ 中没有魔法。

所以过了一会儿,我意识到有宏和预处理器,也许我可以解决这个问题。到目前为止,这是我能想到的:

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

#include "Worker.hpp"
#include "Teacher.hpp"
#include "Programmer.hpp"
# ...

#define PUSH(name)\
name o_##name;\
collection[o_##name.title] = &o_##name;\

using namespace std;

int main() {
map<string, Person*> collection;
PUSH(Worker);
PUSH(Teacher);
PUSH(Programmer);

return 0;
}

我试图自动化 #include directive 但是好像macro 没有变量的概念。并且预处理器不会将宏解释两次。

知道如何实现类似的目标吗?

我知道把我的脑袋埋在这种无用的事情上听起来很愚蠢,但这只是我的特点,如果还没有证明它是对还是错,我就无法摆脱这个想法。

非常感谢您的建议。

编辑:

感谢您为帮助我所做的一切努力。我对这个问题有点不清楚。我真正想要实现的是

我想创建很多程序,让用户决定运行什么。潜在的问题是,我最终可能会得到大量 if-else声明让用户决定运行什么,因为我想在项目中编写大量的小代码。

我不确定这次我是否说清楚了。但是我已经放弃了这个想法,并使用测试框架来完成这项工作。

再次感谢大家。

最佳答案

C++ 具有魔力,它被称为模板。

你可以使用这样的东西......

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


template<class T>
struct make_object {
static_assert(std::is_convertible<T*, Person*>::value, "Object must be derived from Person");
T* object;
make_object() : object(new T) {}
};


//** For iterating over the tuple and inserting each person into the collection
template<std::size_t I = 0, class MAP, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type
insertPeople(MAP& collection, std::tuple<Tp...>& t)
{ }

template<std::size_t I = 0, class MAP, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type
insertPeople(MAP& collection, std::tuple<Tp...>& t)
{
auto object = std::get<I>(t).object;
collection[object->title] = object;
insertPeople<I + 1, MAP, Tp...>(collection, t);
}

//** Creates the tuple containing the objects
template<class... CLASSES>
void createPeople(std::map<std::string, Person*>& collection)
{
std::tuple<make_object<CLASSES>...> objects;
insertPeople(collection, objects);
}

int main()
{
std::map<std::string, Person*> collection;
createPeople<Worker, Teacher, Progammer>(collection);
for (auto person : collection)
std::cout << person.second->title << std::endl;
return 0;
}

完成后不要忘记删除所有对象。或者,您可以使用唯一/共享指针。

关于使用宏的 C++ 动态实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52379200/

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