user4664035
user4664035

Reputation:

How do I create an object once and only once?

I would like the fruit class to be instantiated once and only once at one time, so there would be only one fruit object on the map. When the snake eats it, its destructor is being called and the existence flag is being set to false again. How should I implement this behaviour?

fruit.h

class Fruit {
protected:
    char fruit;
    bool exists;
    int fruitPosX;
    int fruitPosY;
public:
    Fruit();
    char getFruitType();
    int getFruitPosX();
    int getFruitPosY();
    bool getExistenceFlag();
    void setExistenceFlag(bool value);
    ~Fruit();
};

map.cpp

void Map::displayEverythingOnMap(Snake& snake){

    snakeBody* tmp = snake.firstNode;
    while (tmp != NULL) {
        gameArea[snake.getSnakePosX()][snake.getSnakePosY()] = tmp->bodyPart;
        tmp = tmp->next;
    }

    Fruit* fruit = new Fruit;
    fruit->setExistenceFlag(false);
    if (fruit->getExistenceFlag() == false) {
        gameArea[fruit->getFruitPosX()][fruit->getFruitPosY()] = fruit->getFruitType();
        fruit->setExistenceFlag(true);
        if ((fruit->getFruitPosX() == snake.getSnakePosX()) && (fruit->getFruitPosY() == snake.getSnakePosY())) {
            delete fruit;
            fruit->setExistenceFlag(false);
            snake.grow();
        }
    }
}

Upvotes: 2

Views: 1843

Answers (3)

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385174

Don't.

You will only complicate your program and make a strange design, if you try to enforce that only one Fruit can exist at any one time.

Instead, simply create one Fruit and no more.

Upvotes: -1

Tomaz Canabrava
Tomaz Canabrava

Reputation: 2408

You want a singleton:

class Fruit {
protected:
    char fruit;
    bool exists;
    int fruitPosX;
    int fruitPosY;
public:
    static Fruit& instance();
    char getFruitType();
    int getFruitPosX();
    int getFruitPosY();
    bool getExistenceFlag();
    void setExistenceFlag(bool value);
   private:
    Fruit();
    ~Fruit();
};

Fruit& Fruit::instance() {
    static Fruit _self;
    return _self;
}

Because the constructor is private, only functions from the class can call it, and because you have only one method that can create the fruit (the instance() method) it will only create one fruit. ever.

Upvotes: 1

Vittorio Romeo
Vittorio Romeo

Reputation: 93274

I would like the fruit class to be instantiated once and only once at one time, so there would be only one fruit object on the map.

Stop. Having only a single instance of fruit in the map at any given time is a terrible use case for a singleton. You don't need to play around with the lifetime of the object:

  • Simply store an instance of fruit inside your "game state" class whose lifetime as a value. Its lifetime will match the game state's lifetime.

  • When the player collects the fruit, simply increase the snake's length and move the fruit somewhere else. No need to create/destroy objects.


Pseudocode:

struct game_state
{
    fruit _fruit;
    // ...

    game_state()
    {
        _fruit.position = get_random_location();
    }

    void update()
    {
        if(_player.position == _fruit.position)
        {
            grow();
            _fruit.position = get_random_location();
        }
    }
};

Upvotes: 7

Related Questions