好的,所以我正在制作一个基于图块的游戏,我正在从一个文件中加载一个世界。所以我得到一个大约100 x 15个字符的数组,每个字符代表一个磁贴的ID。假设我有32种类型的瓷砖,每种瓷砖都有特殊属性。它们都从Tile类继承,每个都有一个ID 0-31。我想创建一个100 x 15个瓷砖的Tile数组,另一个带有chars的数组会告诉我哪些瓷砖放在哪里。但基本上,我怎样才能最有效地找出ID属于哪个区块?
说,我只读了一个字符,它是3,与某些图块“D”相关。 那么,我应该做这种类型的事情:
switch(idFromChar)
case 0: tile A
case 1: tile B
case 2: tile C
case 3: tile D
这对我来说似乎很慢,不得不这么做。就像我在一个级别中有1000个tile,以及255个类型的tile一样,这是255000个检查来加载该级别。我希望某种类似于Tile类的数组。如:
tileClassArray[0] = A
tileClassArray[1] = B
依旧......
那样,我可以打电话:
(tileClassArray[IDFromChar])(parameters)
作为构造函数,无需遍历每个Tile类。但我不知道如何制作一个类数组,或者如果可能的话。
你得到我想说的话吗?任何帮助都会很好。
答案 0 :(得分:3)
可悲的是,你无法存储构造函数。你必须创建一个模板函数来创建一个对象,然后存储指针,然后你可以通过索引调用该函数。
class Tile { ... }; // base class
class TileA : public Tile { ... };
class TileB : public Tile { ... };
class TileC : public Tile { ... };
...
template<typename T>
Tile* createTile() {
return new T;
};
typedef Tile*(*TileCreator)();
TileCreator creationFuncs[] = {
&createTile<TileA>,
&createTile<TileB>,
&createTile<TileC>,
....
};
Tile* newTile = (creationFuncs[type])();
但是,我无法想到一种方法,在键入方面效率不会O(n)
:)
答案 1 :(得分:2)
那不是真的。 switch
语句可能会被编译为O(1)跳转表。此外,一旦你得到大量的数量的tile,你应该认真考虑根据函数的变化转移到分支 - 即继承,函数对象(包括函数指针)。
答案 2 :(得分:1)
听起来你想要一张地图,它可以很好地使用std::unordered_map
或std::map
。由于您提到每个类都将从父Tile
类继承,因此您可以将地图类型设置为类似
std::map<int, std::shared_ptr<Tile> > tile_map;
现在,您将通过基本循环索引并创建在堆上分配的Tiles来设置地图,以便您可以在地图中放置从Tile
派生的切片。例如:
tile_map[0] = new Derived_Tile_A();
tile_map[1] = new Derived_Tile_B();
//... keep adding to map
访问地图的元素将通过int
类型的键值完成,并且将像普通的数组语法一样完成,除了返回值是指向具有节点的节点的交互器数据元素类型std::shared_ptr<Tile>
。取消引用迭代器后,shared_ptr
可以使用正常的指针退出语法进行操作。
如果需要根据某些条件创建新对象,最好的方法是查看一个基于switch
语句的工厂函数,并返回指向正确派生类型的指针。然后,在为std::map
创建对象时,您将调用工厂函数。
答案 3 :(得分:0)
您可以像创建任何其他数组一样创建类数组。
Tile tileClassArray[255];//makes an array of type classname with 255 members
在一个级别中只有~1000个瓷砖,您最好的选择可能就是将瓷砖存储在如上所示的阵列中。只要级别大小不经常改变,这应该没问题。
我会存储的类是Tile类型。对于每种类型的图块,使用该图块的属性创建一个derrived类。 inheritance
答案 4 :(得分:0)
C ++的反射功能非常有限,所以你所指的并不是直接可能的。即便如此,如果可能的话,开销可能会使其效率远低于switch语句。
如果性能是您的目标,那么switch语句将是您最好的选择。每种情况都在大多数机器语言中实现为单个跳转语句,因此您的255,000个检查可能对应于255,000个指令,大多数现代处理器可以在不到1毫秒的时间内执行。
编辑:请参阅DeadMG的答案,关于跳转表。那个switch语句可能比我描述的更有效。