Object oriented design suggestion

前端 未结 9 2192
余生分开走
余生分开走 2021-02-13 04:43

Here is my code:

class Soldier {
public:
   Soldier(const string &name, const Gun &gun);
   string getName();
private:
   Gun gun;
   string name;
};

cl         


        
相关标签:
9条回答
  • 2021-02-13 05:34

    First off, you'd be violating the Law of Demeter by accessing the Gun from outside the Soldier class.

    I would consider methods like these instead:

    soldier.ArmWeapon(...);
    soldier.Attack(...);
    

    This way you could also implement your fist, knife, grenade, baseball bat, laser cat, etc.

    0 讨论(0)
  • 2021-02-13 05:36

    Indeed, it depends a lot about how much control you want to have.

    To model the real world, you might even want to completely encapsulate the gun object, and just have a soldier.attack() method. The soldier.attack() method would then see whether the soldier was carrying a gun, and what the state of the gun was, and fire or reload it as necessary. Or possibly throw the gun at the target and run away, if insufficient ammunition were present for either operation...

    0 讨论(0)
  • 2021-02-13 05:37

    Encapsulate the functions to provide a consistent UI even if you later change the logic. Naming conventions are up to you, but I normally don't use "getFoo()", but just "foo()" as accessors and "setFoo()" as setters.

    • return reference-to-const when you can (Effective C++ Item #3).
    • Prefer consts, enums, and inlines to using hard coded numbers (Item #4)
    • provide unique naming conventions for your private members to distinguish them from arguments
    • Use unsigned values where they make sense to move errors to compile time
    • When const values, like maximums, apply to an entire class. Make them static.
    • If you plan to inherit, make sure your destructors are virtual
    • initialize all members to sane defaults

    This is how the classes look after that. CodePad

    #include <iostream>
    #include <string>
    #include <stdint.h>
    
    using namespace std;
    
    class Gun 
    {
    public:
       Gun() : _bullets(0) {}
       virtual ~Gun() {}
       void fire() {cout << "bang bang" << endl; _bullets--;}
       void load(const uint16_t bullets) {_bullets = bullets;}
       const int bullets() const {return _bullets;}
    
       static const uint16_t MAX_BULLETS = 17;
    
    protected:
       int _bullets;
     };
    
    class Soldier 
    {
    public:
       Soldier(const string &name, const Gun &gun) : _name(name), _gun(gun) {}
       virtual ~Soldier() {}
       const string& name() const;
       Gun& gun() {return _gun;}
    
    protected:
       string _name;
       Gun _gun;
    };
    
    
    int main (int argc, char const *argv[])
    {
       Gun gun; // initialize
       string name("Foo");
       Soldier soldier(name, gun);
    
       soldier.gun().load(Gun::MAX_BULLETS);
    
       for(size_t i = 0; i < Gun::MAX_BULLETS; ++i)
       {
         soldier.gun().fire();
         cout << "I have " << soldier.gun().bullets() << " left!" << endl;
       }
      return 0;
    }
    
    0 讨论(0)
提交回复
热议问题