2

I'm currently looking at some code i have found on github, however I'm quite confused about some sections of the code and what it does.

What does the line below mean? Key is a bulletType, value is a smart pointer, what is hash<int>?

unordered_map<BulletType, unique_ptr<Bullet>, hash<int> > m_Bullets

What does the below code do?

Does it create a new object of GoodBullet and return an address to it with *this as argument to the constructor?

return std::make_unique<GoodBullet>(*this)

Main code:

#include <iostream>
#include <unordered_map>
#include <string>
#include <memory>
using namespace std;


/** Bullet is the base Prototype */
class Bullet
{
protected:
    string _bulletName;
    float _speed;
    float _firePower;
    float _damagePower;
    float _direction;

public:
    Bullet(){}
    Bullet(string bulletName, float speed, float firePower, float damagePower) 
    : _bulletName(bulletName), _speed(speed), _firePower(firePower), _damagePower(damagePower) 
    {}
    virtual ~Bullet() {}
    virtual unique_ptr<Bullet> clone() = 0;
    void fire(float direction)
    {
        _direction = direction;

        cout << "Name        : " << _bulletName << endl
             << "Speed       : " << _speed << endl
             << "FirePower   : " << _firePower << endl
             << "DamagePower : " << _damagePower << endl 
             << "Direction   : " << _direction << endl << endl;
    }
};

/** SimpleBullet is a Concrete Prototype */
class SimpleBullet : public Bullet
{

public:
    SimpleBullet(string bulletName, float speed, float firePower, float damagePower) :
    Bullet(bulletName, speed, firePower, damagePower)
    {
    }

    unique_ptr<Bullet> clone() override
    {
        return make_unique<SimpleBullet>(*this);
    }
};

/** GoodBullet is the Concrete Prototype */
class GoodBullet : public Bullet
{

public:
    GoodBullet(string bulletName, float speed, float firePower, float damagePower) 
    : Bullet(bulletName, speed, firePower, damagePower) 
    {
    }

    unique_ptr<Bullet> clone() override
    {
        return std::make_unique<GoodBullet>(*this);
    }
};


/** Opaque Bullet type, avoids exposing concrete implementations */
enum BulletType
{
    SIMPLE,
    GOOD
};

/** BulletFactory is the client */
class BulletFactory
{
private:
    unordered_map<BulletType, unique_ptr<Bullet>, hash<int> > m_Bullets;

public:
    BulletFactory()
    {
        m_Bullets[SIMPLE] = make_unique<SimpleBullet>("Simple Bullet", 50, 75, 75);
        m_Bullets[GOOD]   = make_unique<GoodBullet>("Good Bullet", 75, 100, 100);
    }

    unique_ptr<Bullet> createBullet(BulletType BulletType)
    {
        return m_Bullets[BulletType]->clone();
    }
};

int main()
{
    BulletFactory bulletFactory;

    auto Bullet = bulletFactory.createBullet(SIMPLE);
    Bullet->fire(90);

    Bullet = bulletFactory.createBullet(GOOD);
    Bullet->fire(100);
}
uv_
  • 710
  • 2
  • 13
  • 25
  • 1
    regarding your question about `std::make_unique`, here is a good answer to that: [link](https://stackoverflow.com/questions/22571202/differences-between-stdmake-unique-and-stdunique-ptr-with-new) – Duck Dodgers Dec 22 '18 at 14:22
  • 1
    Regarding your first question about what is `hash`, maybe this helps: [link](https://en.cppreference.com/w/cpp/utility/hash) – Duck Dodgers Dec 22 '18 at 14:24

1 Answers1

1

hash<int> is the function which is used to make the keys to the un-ordered map (actually - hash-map) something which can be queried for (and compared to).

return std::make_unique<GoodBullet>(*this):

  1. constructs a GoodBullet (in this case, using the copy-c'tor),

  2. wraps it in an std::unique_ptr<GoodBullet>, and

  3. returns it.

The std::unique_ptr is a smart pointer which doesn't allow copies to be made of it, so you know the instance you got from the clone() is the only instance (unless you constructed a unique_ptr from a pre-existing raw pointer, which you didn't). You can only "move" it to another unique_ptr, and it will also destruct the wrapped GoodBullet when it goes out-of-scope.

uv_
  • 710
  • 2
  • 13
  • 25