Расширение / увеличение счетчика ссылок интеллектуального указателя

Предположим, у меня есть метод, определяющий shared_ptr. После завершения метода shared_ptr также будет удален. Тем временем у меня есть еще один участник, который использует это shared_ptr. Поэтому я хотел бы продлить время жизни shared_ptr за пределы исходного метода.

void initial_method(int input)
{
  std::shared_ptr<int> a { std::make_shared<int>(input) };
  some_delayed_method(a);
}

Можно ли вручную увеличить счетчик ссылок a на единицу в этом примере?

some_delayed_method() подобен отряду и относится к a сразу после того, как initial_method() вернулся.


person OS2    schedule 27.10.2020    source источник
comment
Тебе не нужно этого делать. std::shared_ptr действителен на время вызова метода.   -  person Mansoor    schedule 28.10.2020
comment
Простого создания копии shared_ptr должно быть достаточно для продления срока службы int, на которую он указывает, вы это имели в виду?   -  person Jeremy Friesner    schedule 28.10.2020
comment
@ M.A Вы читали вопрос?   -  person OS2    schedule 28.10.2020
comment
Пожалуйста, отредактируйте свой вопрос и поясните, в чем проблема: я вижу, что по крайней мере два человека (включая меня) неправильно его поняли. Может быть, покажите больше вашего кода. Возможно, добавьте несколько операторов печати, которые показывают, в чем проблема.   -  person anatolyg    schedule 28.10.2020
comment
@ OS2 Вы отредактировали свой вопрос, что полностью меняет его объем! В любом случае вы должны показать код для some_delay_method.   -  person Mansoor    schedule 28.10.2020
comment
Отвечает ли это на ваш вопрос? Как освободить указатель от boost :: shared_ptr?   -  person anatolyg    schedule 29.10.2020


Ответы (2)


Поскольку вы не можете вызвать some_delayed_method без shared_ptr для объекта, а any shared_ptr для объекта продлевает его время жизни, вам ничего не нужно делать.

person David Schwartz    schedule 27.10.2020
comment
@ OS2 Я прочитал это еще раз и поддерживаю этот ответ. Независимо от того, какой код вызывает some_delayed_method, когда и как бы он ни был вызван, он должен удерживать std::shared_ptr до a, что уже удерживает его. - person David Schwartz; 28.10.2020

Если some_delayed_method сохраняет указатель в какой-то внешней структуре данных, и этот указатель будет использоваться позже, вы должны использовать для этого shared_ptr.

class X
{
public:
    void initial_method(int input)
    {
        std::shared_ptr<int> a { std::make_shared<int>(input) };
        some_delayed_method(a);
    }

    void some_delayed_method(const std::shared_ptr<int>& a)
    {
        use_later = a;
    }

private:
    std::shared_ptr<int> use_later;
}

Таким образом, счетчик ссылок будет обрабатываться автоматически.


Вы можете настоять на использовании необработанного указателя, чтобы сохранить данные на будущее:

void some_delayed_method(const std::shared_ptr<int>& a)
{
    use_later = a.get();
}

...

int* use_later;

Это неправильный способ сохранения данных. Чтобы он работал (или казался работающим), вам нужно кое-что взломать. Например, сделайте еще одну ссылку на данные и опустите ее:

void some_delayed_method(const std::shared_ptr<int>& a)
{
    use_later = a.get();
    new std::shared_ptr<int>(a); // horrible hack; please never do it! but it works...
}

Этот взлом приводит к утечке выделенного std::shared_ptr, поэтому его нельзя удалить, поэтому его счетчик ссылок не уменьшается, а выделенный int утекает.

person anatolyg    schedule 27.10.2020
comment
Взлом действительно приводит к утечке newly выделенного std::shared_ptr, поэтому он никогда не может быть deleted, таким образом, refcount выделенного int не уменьшается, а также утечка. - person Remy Lebeau; 28.10.2020
comment
Спасибо за описание, как это работает! Я забыл упомянуть, что произошла утечка самого объекта int. - person anatolyg; 28.10.2020
comment
Хорошо спасибо. Я искал способ не делать вторую копию. С такой скоростью я мог бы просто использовать вместо этого необработанный указатель (новое удаление). - person OS2; 28.10.2020
comment
Это use_later = a; было выполнено до вызова some_delayed_method(). С таким же успехом я мог бы использовать необработанный указатель. - person OS2; 28.10.2020
comment
Почему вы предлагаете намеренно утечку памяти ... с помощью умного указателя на все вещи? - person Passer By; 28.10.2020
comment
@ OS2 Не забывайте, что у вас есть возможность использовать shared_ptr для хранения дополнительной ссылки, как я описал в первой части моего ответа. Это правильное решение, без взломов. - person anatolyg; 28.10.2020
comment
@anatolyg Ваш второй момент даже не очевиден, поэтому IDK, почему вы подняли его. Вопрос остается без ответа. - person OS2; 28.10.2020