我有一个普通的类Player,在类中我声明了一个较小类的对象,例如Weapon,Inventory等。
当然,我使用指针(shared_ptr)来实例化我的Player对象,并使用相同的方法来实例化我的类的任何对象。我应该继续这样做,还是应该尝试通过不使用指针使其变得更简单,这会带来一定的劣势吗?
class Player: public Human, public Control
{
public:
Player();
~Player(){};
private:
Weapon myWeapon;
std::vector<std::tr1::shared_ptr<Weapon> > WeaponsList;
};
VS
class Player: public Human, public Control
{
public:
Player();
~Player(){};
private:
Weapon myWeapon;
std::vector<Weapon> WeaponsList;
};
注意,我使用shared_ptr并希望保留一个选项,让Weapon在某个时刻成为基类(但不要急!)。
答案 0 :(得分:2)
绝对是前者(即是,继续使用指针),只需确保定义灵活的抽象类Weapon
,其中包含玩家需要与之交互的所有方法/属性;你想避免尽可能地解析派生类型(这会使代码变得混乱而且有点慢)。
如果您不熟悉设计模式,我建议您阅读Factories以及如何在这种情况下使用它们来处理分配。如果有人想在以后为您的游戏添加其他武器,这将使您的代码易于维护/理解。您将需要使用命名标记来阐明您的代码并选择要在您的工厂中构建的对象;这可以使用enum
来完成,但如果您不能使用强类型enum
(c ++ 11),我倾向于更喜欢名称空间或结构,例如:
struct WeaponID
{
static const int DESERT_EAGLE = 0;
static const int SHOTGUN = 1;
}
// ... use in a switch/case e.g. WeaponID::SHOTGUN
您可以轻松查看如何在交换机中使用此类标记并输出指向抽象类的共享指针(如果需要,您甚至可以定义别名标记)。
如果您怀疑可能需要经常解析派生类型,那么考虑将前一个标记存储为抽象类的成员,这将比使用dynamic_casts
更容易和更清晰。
如果你担心性能(我认为你是120 fps),考虑使用memory pools对象(武器,玩家等),虽然在游戏的背景下,我希望游戏开始时对象的数量(几乎)是不变的?
答案 1 :(得分:2)
根据最初提供的信息,我认为唯一的答案是&#34;这取决于&#34;。
WeaponsList
是指针向量,那么负责清除各种Weapon
对象的是什么? WeaponsList
是Weapon
的向量,则需要确保复制构造函数已完成。Weapon
?它是一个基类,您将从中派生Sword
,Dagger
,Lance
等?或者武器的类型只是对象的属性?Weapon
对象是否可以在没有Player
的情况下存在?是否会有所有Player
个对象指向的武器共享列表?换句话说,我认为我们没有足够的细节来完整回答你的问题。
通过评论中提供的其他信息:
如果你创建一个对象,它需要被清除(销毁);当您使用shared_ptr时,应该自动处理。
由于Weapon
可以在没有Player
的情况下存在并且可能在将来成为基类,因此使用指针向量可能是要走的路。