【发布时间】:2017-09-19 06:45:12
【问题描述】:
我有许多类型的游戏对象,它们在某些方面相互关联。
所有关系都由Map<K1,K2> 实现。
#include <vector>
using namespace std;
template<class K1,class K2> class Map{ //N:N relation
public: std::vector<K2*> getK2(K1* k1){/* some code */return std::vector<K2*>();}
public: std::vector<K1*> getK1(K2* k2){/* some code */return std::vector<K1*>();}
//... various function ...
};
这里是方便所有关系查询的集线器类GameRelation:-
(只是一个例子,不需要注意所有细节)
class Human{}; class House{}; class Dog{};
class GameRelation{
public:
#define RELATION(A,B,EnumName) Map<A,B> Map##EnumName; \
enum EnumName##Enum{EnumName}; \
std::vector<B*> getAllRight(EnumName##Enum e,A* a){ \
return Map##EnumName.getK2(a); \
}
//... various function ...
RELATION(Human,House,Own)
//I can insert any relation that I want
};
上面的宏扩展成类似的东西:-
Map<Human,House> MapOwn;
enum OwnEnum{Own};
std::vector<House*> getAllRight(OwnEnum e,Human* a){
return MapOwn.getK2(a);
}
这是它的使用方法(full demo):-
int main() {
GameRelation gameRelation;
std::vector<House*> houses=gameRelation.getAllRight(GameRelation::Own,new Human());
//get all "House" that is "Own" by a "Human"
return 0;
}
经过一些测试,它运行良好。每个人都对神奇的结果感到满意。
但是,我的意识告诉我,这是一个 hack。
对于内容辅助(例如智能感知)和自动重构来说,这也有点糟糕。
如果我想将他们的实现转移到.cpp,我还需要 awesome hacking X-MACRO。
问题:
- 有什么优雅的(不那么hack的)方法吗?这是什么?
“否”可以是一个有效的答案。 - 当我需要这种(奇怪的)功能时,X-MACRO 是(专业的)方法吗?
【问题讨论】:
-
using namespace std;?哦,来吧,你比那更好...... -
看起来您正试图用命令式编程语言中的枚举和宏来重塑关系数据模型。您是否考虑过只使用 SQLite 之类的东西?您可能有一个表“house”、一个表“human”和一个表“house_ownership”,其中前两者的外键。
-
@Quentin 同意,这只是为了演示。这是“ideone”的默认设置。
-
@Christian Hackl 是的,我也感觉到了,但我从来不知道有这样的图书馆。谢谢。 SQLite 是否使用哈希函数?我讨厌哈希,它很慢。 (我已经分析了 std::unordered_map。)
-
@javaLover:我不知道 SQLite 是如何实际实现的,但是当您需要本地基于文件的关系数据库时,它是标准的行业解决方案。例如,Android、iOS、Firefox 和最新的 Visual Studio IDE 都使用它。但是,如果您需要完全在内存中的东西并且负担不起 I/O 操作,那么它可能是错误的选择。
标签: c++ enums macros c++14 x-macros