Neosapien
Neosapien

Reputation: 177

How do you create objects that have an instance pointer of itself in a loop?

I have the following class:

class Worker
{
private:
    const int m_id;
    Worker* m_partner = nullptr;
public:
    Worker(const int &id)
        :m_id(id){}

    Worker(const int &id, Worker partner)
        :m_id(id)
    {
        m_partner = &partner;
    }
}

When I create a vector of workers like this:

std::vector<Worker> workers;
workers.push_back(Worker(0, Worker(1)));
workers.push_back(Worker(2, Worker(3)));
workers.push_back(Worker(4, Worker(5)));

I get a good vector of worker-partner objects, with ids 0-1, 2-3 and 4-5. How can I create this in a for loop? When I try this:

for (int id = 0; id < 6; id += 2)
{
    workers.push_back(Worker(id, Worker(id+1)));
}

all main workers are being partnered with partner 5, a.k.a. the last partner worker object created. Thanks in advance.

Upvotes: 0

Views: 55

Answers (1)

Some programmer dude
Some programmer dude

Reputation: 409166

The problem is in the constructor:

Worker(const int &id, Worker partner)

You define the argument partner as a local variable, and its life-time will end (and the object be destructed) when the function returns. This means any pointer to this variable will become invalid as soon as the constructor function returns.

You need to pass this argument either by reference or as a pointer (and the original object needs to stay alive and valid as long as the Worker object you create lives).


If you the object you pass to the constructor won't be alive long enough (as in the example in the question) then you need to make a copy of the partner object:

Worker(const int id, Worker partner)
    : m_id(id), m_partner(std::make_unique<Worker>(std::move(partner)))
{
}

[Note that the id argument doesn't need to be passed by reference]

Instead of using plain pointer I recommend you use smart pointers, like std::unique_ptr. Then you won't have to worry about needing your own copy-constructor, destructor or such:

std::unique_ptr<Worker> m_worker;

This will make Worker objects impossible to copy. If you need copying then use std::shared_ptr (and std::make_shared) instead.

Upvotes: 3

Related Questions