Reputation: 185
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
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