vendredi 3 mars 2017

Is this use of raw pointers in modern C++ bad practice?

I want to hold a vector of Base class instances without object slicing (Such that I can also store instances of a child of Base without issue) while maintaining polymorphic behaviour without adding to the list by copying values, but rather by reference.

Consider the following source file:

#include <iostream>
#include <string>
#include <vector>
#include <memory>

class Entity
{
public:
    Entity(){this->edited = false;}
    virtual std::string name() = 0;
    bool edited;
};

class Player: public Entity
{
public:
    Player(): Entity(){}
    std::string name(){return "player";}
};

int main()
{
    std::vector<Entity*> entities;
    Player p;
    entities.push_back(&p);
    entities.at(0)->edited = true;
    Entity* ent = entities.at(0);
    std::cout << "ent = " << ent->name() << ", edited = " << ent->edited << ".\n";
    return 0;
}

I obtain the following output:

ent = player, edited = 1.

As the output shows (via printing out "player" and showing the change in 'edited'), polymorphic behaviour is maintained due to the raw pointer and I am able to edit members of the list without issue.

To clarify what I'm asking: Could I instead use an std::reference_wrapper to achieve the exact same behaviour? When I tried using a reference_wrapper, the same behaviour could not be achieved as pointers are required to achieve this polymorphic behaviour? If reference_wrappers are not a viable alternative, although I know full-well that the instance of Player that I added to the vector is a stack-variable, would it be sensible to instead use a shared_ptr? In my particular example I would favour a shared_ptr due to the fact that I want shared ownership of the members of the vector. Are there any better ways of achieving this behaviour?

Aucun commentaire:

Enregistrer un commentaire