agiro
agiro

Reputation: 2080

Passing shared_ptr to function - clarification needed

I have a class with the member

vector<shared_ptr<ParticleSystem>> particleSystems;

which has a method

void AddParticleSystem(shared_ptr<ParticleSystem> const sys)
{
    particleSystems.push_back(sys);
}

note the parameter. The method is called like so:

shared_ptr<ParticleSystem> psys = make_shared<ParticleSystem>(...);
scene.AddParticleSystem(psys);

It works, but why? Doesn't this get shared?


By default I don't try to pass around pointers. When considering function parameters, I either use const& when wish not to change anything on the passed variable or use & when plan to use methods that will change members of the given variable.

So By default I implemented the above method like so:

void AddParticleSystem(ParticleSystem const& sys)
{
    particleSystems.push_back(std::make_shared<ParticleSystem>(sys));
}

that I call like

shared_ptr<ParticleSystem> psys = make_shared<ParticleSystem>(...);
scene.AddParticleSystem(*psys);

This time it doesn't compile, stating

Error C2280 'Physics::ParticleSystem::ParticleSystem(const Physics::ParticleSystem &)': attempting to reference a deleted function

I traced back the issue using Output (I use VS) which has led me to

particleSystems.push_back(std::make_shared<ParticleSystem>(sys));

to the make_shared method, to be precise.

Now, This ParticleSystem extends Visual that has constructors and members like

Visual(string const &name, string const &path, const char* vertexPath, const char* fragmentPath, const char* geometryPath = nullptr, bool gamma = false)
{
    this->name = string().append(name);
    model = make_unique<Model>(path, gamma);
    material = make_unique<Material>();
    shader = make_unique<Shader>(vertexPath, fragmentPath, geometryPath);
}

unique_ptr<Shader> shader;
unique_ptr<Material> material;
unique_ptr<Model> model;
virtual ~Visual() = default;

I get make_shared needs to copy stuff somehow. Is the problem that a ParticleSystem which is a Visual has unique_ptr members and by default make_shared knows not how to treat them?

Is this the reason the compiler deleted my default copy constructor? And if so, if I implement a copy constructor for all the classes that Visual has, including itself, I can pass that ParticleSystem const& as a parameter?

Upvotes: 0

Views: 101

Answers (1)

David Schwartz
David Schwartz

Reputation: 182753

Each copy of a shared_ptr is a handle by which the shared object can be accessed. You can pass around references to the shared_ptr or copies of it and store copies of it in collections. Copies of shared_ptrs refer to the same underlying object. When the last shared_ptr that refers to the same underlying object is destroyed, the underlying object is destroyed.

Upvotes: 2

Related Questions