Here is my code:
class Soldier {
public:
Soldier(const string &name, const Gun &gun);
string getName();
private:
Gun gun;
string name;
};
cl
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.
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...
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.
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;
}