Общий указатель (это) - PullRequest
       28

Общий указатель (это)

0 голосов
/ 22 апреля 2020

У меня есть исключение: 0x74AC4192 в main.exe: Microsoft C ++ исключение: std :: bad_weak_ptr в ячейке памяти 0x001AF0D0.

в

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);
}

Я также использовал это в заголовок:

class Gasstation : public std::enable_shared_from_this<Gasstation>

В чем может быть проблема?

1 Ответ

1 голос
/ 22 апреля 2020

Проблема с вашим кодом здесь заключается в том, что вы вызываете shared_from_this() внутри конструктора самого класса, где, строго говоря, он еще не был "передан в общий доступ". Конструктор вызывается до , существует умный указатель на объект. Следуя вашему примеру, если вы создаете от shared_ptr до Gasstation:

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

Это ограничение enable_shared_from_this, что shared_from_this нельзя вызывать в конструкторе.

One Решение, хотя и не такое элегантное, заключается в использовании метода publi c, который устанавливает переменную cashregisters_. Метод можно вызывать после создания:

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();

Это решение потребует от вас не забывать вызывать initialise_cashregisters при каждой инициализации Gasstation.

Если не считать этого, ваши возможности ограничены, и вам, возможно, придется пересмотреть свой дизайн. Рассматривали ли вы использование необработанных указателей на Gasstation в Cashregister вместо умных указателей? Если cashregister_ является частной переменной и никогда не будет существовать после срока службы Gasstation, которой она назначена, использование необработанных указателей может быть безопасной и элегантной альтернативой.

...