Beszteri
Beszteri

Reputation: 185

Shared pointer (this)

I have got an exception throw :0x74AC4192 in main.exe: Microsoft C++ exception: std::bad_weak_ptr at memory location 0x001AF0D0.

in

Gasstation::Gasstation(int n,int m)
{
    for (int i = 0; i < n; ++i)
    {
        pumps_.push_back(std::make_shared<Pumplace>());
    }
    cashregisters_ = std::make_shared<Cashregister> (shared_from_this(), m);
}

I also used this in the header :

class Gasstation : public std::enable_shared_from_this<Gasstation>

What could be the problem?

Upvotes: 0

Views: 113

Answers (1)

Azam Bham
Azam Bham

Reputation: 1399

The issue with your code here, is that you are calling shared_from_this() within the constructor of the class itself, where strictly speaking, it has not been "made shared" yet. The constructor is called before a smart pointer to the object exists. To follow your example, if creating a shared_ptr to Gasstation:

std::shared_ptr<Gasstation> gasStation = std::make_shared<Gasstation>(5,10);
//gasStation is available as a smart pointer, only from this point forward

Its a limitation of enable_shared_from_this that shared_from_this cannot be called in a constructor.

One solution, though not as elegant, is to have a public method that sets the cashregisters_ variable. The method can be called after construction:

Gasstation::Gasstation(int n, int m)
{
    for (int i = 0; i < n; ++i)
    {
        pumps_.push_back(std::make_shared<Pumplace>());
    }
    cashregisters_ = std::make_shared<Cashregsiter>(m);
}

Gasstation::initialise_cashregisters()
{
    cashregisters_->set_gasstation(shared_from_this());    
}

//driver code
std::shared_ptr<Gasstation> gasStation = std::make_shared<Gasstation>(5, 10);
gasStation->initialise_cashregisters();

This solution will require you to remember to call initialise_cashregisters every time you initialise Gasstation.

Short of that, your options are limited, and you may have to rethink your design. Have you considered using raw pointers-to-Gasstation in Cashregister instead of smart pointers? If cashregister_ is a private variable and will never exist beyond the lifetime of the Gasstation it is assigned to, using raw pointers may be a safe and elegant alternative.

Upvotes: 2

Related Questions