C++ 在类中创建对象的最佳实践

C++ 在类中创建对象的最佳实践,c++,class,heap,C++,Class,Heap,我有一个普通类玩家,在类中我声明了一个较小类的对象,例如武器、库存等 当然,我已经使用指针shared_ptr来实例化我的Player对象,并使用相同的方法来实例化我的类中的任何对象。我应该继续这样做,还是应该尝试通过不使用指针使它变得更简单,这会带来一定的缺点 class Player: public Human, public Control { public: Player(); ~Player(){}; private:

我有一个普通类玩家,在类中我声明了一个较小类的对象,例如武器、库存等

当然,我已经使用指针shared_ptr来实例化我的Player对象,并使用相同的方法来实例化我的类中的任何对象。我应该继续这样做,还是应该尝试通过不使用指针使它变得更简单,这会带来一定的缺点

class Player: public Human, public Control
    {
    public:
        Player();
       ~Player(){};

    private:
        Weapon           myWeapon;
        std::vector<std::tr1::shared_ptr<Weapon> > WeaponsList;

    };
vs


注意,我使用shared_ptr,并希望保留一个选项,让武器在某个时刻成为基类,但不要匆忙

肯定是前一个ie是的,继续使用指针,只需确保你定义了一个灵活的抽象类武器,其中包含玩家需要与之交互的所有方法/属性;您希望尽可能避免解析派生类型,这会使代码凌乱且速度稍慢

如果您不熟悉设计模式,我建议您阅读相关内容,以及如何在这种情况下使用它们来处理分配。这将使您的代码易于维护/理解,如果以后有人想在您的游戏中添加其他武器。您需要使用命名标记来澄清代码,并选择要在工厂中构建的对象;这可以使用枚举来完成,但如果不能使用强类型枚举c++11,我倾向于使用名称空间或结构,例如:

struct WeaponID
{
    static const int DESERT_EAGLE = 0;
    static const int SHOTGUN = 1;
} 
// ... use in a switch/case e.g. WeaponID::SHOTGUN
您可以很容易地看到如何在开关中使用这些标记,并输出一个指向抽象类的共享指针,您甚至可以在需要时定义别名标记

如果您怀疑您可能需要经常解析派生类型,那么考虑将先前的标记存储为抽象类的成员,这将使它比使用DycimaCasts更容易和更干净。p>


如果你担心的是,在我想象的120 fps的情况下,考虑使用武器、玩家等,虽然在游戏的背景下,我预计游戏开始时物体的数量几乎是恒定的。

< P>最初提供的信息,我认为唯一的答案是它取决于。 如果你的武器清单是指针向量,那么什么负责清除各种武器对象? 如果武器列表是武器的向量,则需要确保复制构造函数是完整的。 什么是武器?它是一个基础类,你将从中获得剑、匕首、长矛等。?或者武器类型仅仅是物体的一种属性? 没有玩家,武器对象可以存在吗?是否会有所有玩家对象指向的武器共享列表? 换句话说,我认为我们没有足够的细节来完全回答你的问题

使现代化 在评论中提供了附加信息:

如果您创建了一个对象,则需要将其清除或销毁;当您使用shared_ptr时,应该自动处理


由于武器可以在没有玩家的情况下存在,并且将来可能成为基类,因此使用指针向量可能是一种可行的方法

武器是多态类型吗?呃。。。类Player的构造函数不叫Player,而叫gPlayer吗?为什么MountNumber在ints上工作,而我的武器是武器类型?为什么会员是公众的?为什么rWeapon向成员返回非常量引用?为什么指针的使用是一种自然现象?为什么Draw是玩家的成员?Ohmagawd…:-还没有,我尽量保持简单,但里面有一个弹药物体。我想保留这个选项,让它在某个时候具有多态性。@DevSolar:问题太多了。。不要在不知道里面是什么的情况下拿出代码,并坚持问题。我有42k行代码,可以很好地工作,其中20k个对象表现得很漂亮,碰撞和射击,速度稳定,每秒120帧。@DevSolar。没有冒犯。请注意,在需要维护的代码上工作(例如在studio中工作并可供他人阅读)与爱好编程之间存在差异。我已经在这个项目上偶尔工作了5年,没有任何困难回到它,即使是一年的休息。在42k代码中,引擎运行平稳,到目前为止我没有遇到任何bug。如果将来,当我计划扩展它时,它开始崩溃,我将重新考虑并更多地思考一个有缺陷的游戏设计。要点1:这是一个共享的ptr。我必须清理它吗?第2点:与第1点相同第3点:武器目前单独存在,在以后的某个阶段可能会变得多态。第四点:是的can@user2856452; 根据你的评论更新了我的答案。谢谢,这是个好答案!是的,我就是这么想的。这取决于我将来想拥有武器成为一个基类。干杯……是的,我保持数量不变并保留记忆。对象在实际游戏开始之前初始化。我喜欢你关于抽象类的想法。武器是一个灵活的类,通过读取的外部文件添加。我的武器使用枚举,但没有在这里显示。我避免二元施放。我创建了一个二级列表,其中包含指向我创建的对象的指针
例如,控制对象并使用它们。我对动态强制转换感到畏缩,这可能是不合理的,而且作为例外,只有很少的调用。。不知道,你怎么看?@user2856452我认为动态施法并不意味着精髓经常使用。当你可以的时候远离它们是很好的,正如我所说的,如果你知道你需要经常解析派生类,那么提前计划和存储ID是很容易的。是的,这可以追溯到关于游戏设计的讨论。有一些事情我甚至觉得它们是错误的,比如动态强制转换,但还有一些事情,比如sigleton,我完全同意,因为我注意到它们的缺点,它们实际上简化了我的代码。一般来说,我对游戏设计不是教条式的,只要它符合我未来的目标。我只是按照你的建议读了一些关于工厂的书。我在我的游戏中有这个或类似的实现,但我不知道它被称为like factory。基本上,我从游戏编辑器创建的文件中读取,该文件将其解析为枚举并传递给工厂函数,以返回要添加到通用基类列表中的正确对象。我没有遇到任何问题,就我所理解的,这似乎与保理应该是什么相似。
struct WeaponID
{
    static const int DESERT_EAGLE = 0;
    static const int SHOTGUN = 1;
} 
// ... use in a switch/case e.g. WeaponID::SHOTGUN