Существует ли такая вещь, как интеллектуальный указатель с подсчетом общих ссылок?

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

Однако мне кажется, что должна быть возможность создать специальный вид shared_ptr, который позволяет избежать проблемы цикла, связывая счетчик ссылок всех указателей в цикле. И поскольку я могу придумать, как это сделать, мне интересно, существует ли такая вещь?

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

#define BOOST_NO_MEMBER_TEMPLATE_FRIENDS

#include <boost/shared_ptr.hpp>
#include <iostream>

template <typename T>
struct shared_count_ptr
{
boost::shared_ptr<T> innerPtr;
template <typename TT>
void link( boost::shared_ptr<T> & sharedPtr, boost::shared_ptr<TT> & linked )
{
innerPtr    = sharedPtr;
innerPtr.pn = linked.pn;
}
};

struct Hand;
struct Arm
{
Arm()  { std::cout << "Creating Arm\n";   }
~Arm() { std::cout << "Destroying Arm\n"; }

shared_count_ptr<Hand> hand;
};

struct Hand
{
Hand()  { std::cout << "Creating Hand\n";   }
~Hand() { std::cout << "Destroying Hand\n"; }

shared_count_ptr<Arm> arm;
};

int main()
{
boost::shared_ptr<Arm> savedArm;

std::cout << "Scope 0 entered\n";
{
std::cout << "\tScope 1 entered\n" ;

boost::shared_ptr<Arm> arm( new Arm );
{
std::cout << "\t\tScope 2 entered\n";
boost::shared_ptr<Hand>  hand( new Hand );

hand->arm.link( arm, arm->hand );
arm->hand.innerPtr = hand;

savedArm = arm;
}
std::cout << "\t\tScope 2 exited\n";
}
std::cout << "\tScope 1 exited\n";
std::cout << "\tScope 0 about to exit\n";

return 0;
}

Общая концепция заключается в том, что в глазах воображаемого shared_count_ptrРука и рука — фактически один и тот же объект.

Так:

  • Существует ли такая мысль в boost?
  • Если нет, то потому что это ужасная идея? (Или я только что придумал что-нибудь умное?)

1

Решение

Вот простой тест. Создайте полный граф на 17 вершинах так, чтобы программа указывала только на вершину 0. Начните удалять ребра случайным образом. Ваша идея работает? (Спойлер: это не так).

2

Другие решения

Я бы вообразил тебя мог сделать что-то в этом направлении. Однако в такой структуре каждый указатель A должен знать о каждом другом указателе B, такой что либо B может быть достигнуто с A или наоборот. Я не понимаю, как это может масштабироваться до более чем небольшого числа взаимосвязанных указателей.

Казалось бы, если вы хотите поддерживать циклические ссылки без какой-либо помощи со стороны программиста, вам более или менее нужен полноценный сборщик мусора, а не простая схема подсчета ссылок (я бы хотел, чтобы в этом ошиблись).

1

По вопросам рекламы [email protected]