Достойная реализация shared_ptr, которая не требует массивной библиотеки? - PullRequest
6 голосов
/ 03 октября 2009

Я сейчас беру класс программирования C ++ по ГИС-программированию. Я действительно начинаю получать много головной боли от работы с правильным управлением памятью. Учитывая, что в любое время часто есть 8-10 классов, каждый из которых содержит указатель на трехмерную матрицу или что-то еще очень большое. Теперь наш класс уже поднял вопрос о prof, позволяющем нам использовать Boost или, по крайней мере, C ++ Feature Pack для 2008 (для TR1). Он отказался, но сказал, что если мы хотим, мы можем найти добавить несколько сторонних файлов cpp / hpp. Я уже пробовал смотреть на получение shared_ptr из буста, но это скорее головная боль, чем стоит.

Так есть ли какая-нибудь бесплатная реализация shared_ptr?

Ответы [ 7 ]

17 голосов
/ 03 октября 2009

Используйте инструмент boost's bcp . Это позволит вам извлечь определенные функции из библиотек наддува.

bcp shared_ptr /boost_shared_ptr

извлечет shared_ptr и его зависимости от этого каталога.

4 голосов
/ 03 октября 2009

Дайте Lokis умный указатель с пересчетом подсчитал - насколько я помню, он менее связан, а затем повышает заголовки.

3 голосов
/ 03 октября 2009

Заголовок повышения препроцесса, который содержит определение shared_ptr. Запишите это в один файл .hpp. Таким образом, вы получите boost shared_ptr и все его зависимости в одном заголовочном файле, без необходимости полной установки boost.

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

1 голос
/ 16 июля 2010

Я только что заметил серьезную ошибку в вашем примере кода. Должно быть

ref_count_(p ? new int(0) : NULL)

вместо

ref_count_(p ? new int : NULL)

счетчик должен быть установлен в 0. если не все ваши умные указатели больше не умны. Все те программисты, которые делают эту крошечную ошибку, много платят за нее позже, вы должны думать как компилятор и вести себя так ...

1 голос
/ 03 октября 2009

Вы действительно нуждаетесь в долевой собственности?

Зачастую вы можете обойтись просто с помощью специального специального класса RAII, получающего исключительное право собственности на объект.

Управление памятью без RAII - это боль, но вы получаете RAII без shared_ptr.

1 голос
/ 03 октября 2009
#include <tr1/memory> // this is contained in STL.
std::tr1::shared_ptr<A> a = new A;

ау, только что увидел, что ваш профессор не позволяет вам использовать TR1. неудача.

1 голос
/ 03 октября 2009

Хотя это было бы ужасной идеей для производственного решения, было бы не так сложно подготовить свой собственный класс, если бы вы не пытались быть кросс-компилятором, гибким и потокобезопасен как буст:

template <typename contained>
class my_shared_ptr {
public:
   my_shared_ptr() : ptr_(NULL), ref_count_(NULL) { }

   my_shared_ptr(contained * p)
     : ptr_(p), ref_count_(p ? new int : NULL)
   { inc_ref(); }

   my_shared_ptr(const my_shared_ptr& rhs)
     : ptr_(rhs.p), ref_count_(rhs.ref_count_)
   { inc_ref(); }

   ~my_shared_ptr() {
     if(ref_count_ && 0 == dec_ref()) { delete ptr_; delete ref_count_; }
   }
   contained * get() { return ptr_; }
   const contained * get() const { return ptr_; }

   void swap(my_shared_ptr& rhs) // throw()
   {
      std::swap(p, rhs.p);
      std::swap(ref_count_, rhs.ref_count_);
   }

   my_shared_ptr& operator=(const my_shared_ptr& rhs) {
        my_shared_ptr tmp(rhs);
        this->swap(tmp);
        return *this;
   }

   // operator->, operator*, operator void*, use_count
private:
   void inc_ref() {
      if(ref_count_) { ++(*ref_count_); }
   }

   int  dec_ref() {
      return --(*ref_count_);
   }

   contained * ptr_;
   int * ref_count_;
};
...