Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Покритикуйте мой smart pointer 
:(
    Опции темы
Hassel
Дата 20.6.2011, 21:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 13.1.2011
Где: Москва

Репутация: нет
Всего: нет



Написал свою реализацию умного указателя (в чисто учебных целях).
Хотелось разобраться в теме. Буду очень рад комментариям.

Честно говоря меня смущает проверка на "нулевость" указателя ( is_null() ).
Как-то не красиво получилось.

Код

template<class T>
class smrt_ptr
{
private:
  T*    internal_pointer;
  long int*  internal_counter;

public:
  smrt_ptr()
  {
    internal_pointer = new T();
    internal_counter = new long int;
    *internal_counter = 1;
  }

  smrt_ptr( T* t )
  {
    internal_pointer = t;
    internal_counter = new long int;
    *internal_counter = 1;
  }

  ~smrt_ptr()
  {
    --(*internal_counter);

    if(*internal_counter < 1)
    {
      delete internal_pointer;
      delete internal_counter;
    }
  }

  smrt_ptr( const smrt_ptr<T>& ptr )
  {
    internal_pointer = ptr.internal_pointer;
    internal_counter = ptr.internal_counter;
    (*internal_counter)++;
  }

  bool is_null(){ return !internal_pointer; }

  T* operator->()
  {
    return internal_pointer;
  }

  T& operator*()
  {
    return *internal_pointer;
  }

  operator T*()
  {
    return internal_pointer;
  }

  smrt_ptr<T>& operator=( const smrt_ptr<T>& ptr )
  {
    internal_pointer = ptr.internal_pointer;
    internal_counter = ptr.internal_counter;
    ++(*internal_counter);
    return *this;
  }

  template<class U>
  bool operator==( const smrt_ptr<U>& ptr )
  {
    return ptr.internal_pointer == internal_pointer;
  }
};

PM MAIL   Вверх
azesmcar
Дата 20.6.2011, 21:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Hassel

Ну что же, поехали.
1. будет утечка памяти при использовании оператора присваивания.
2. тут было бы правильнее ссылаться на NULL вместо создание объекта.
Код

smrt_ptr()
  {
    internal_pointer = new T();
    internal_counter = new long int;
    *internal_counter = 1;
  }

3. Функция is_null лучше заменить оператором !.
4. нет перегрузок для константой версии объекта, да и вообще нет константный функций, хотя многие из них ничего не модифицируют.
ну и всякие мелочи типа не использования списка инициализации, еще например эти 2 строки
Цитата(Hassel @  20.6.2011,  21:13 Найти цитируемый пост)
internal_counter = new long int;
    *internal_counter = 1;

можно написать проще
Код

internal_counter = new long int(1);

дальше лень смотреть.. smile 

Это сообщение отредактировал(а) azesmcar - 20.6.2011, 21:45
PM   Вверх
Hassel
Дата 20.6.2011, 22:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 13.1.2011
Где: Москва

Репутация: нет
Всего: нет



Ага, понял. Там не только оператор присваивания, там и конструктор копирования такой-же.
Вот так правильно?
Код

  smrt_ptr<T>& operator=( const smrt_ptr<T>& ptr )
  {
    --(*internal_counter);

    if(*internal_counter < 1)
    {
      delete internal_pointer;
      delete internal_counter;
    }

    internal_pointer = ptr.internal_pointer;
    internal_counter = ptr.internal_counter;
    ++(*internal_counter);
    return *this;
  }

  smrt_ptr( const smrt_ptr<T>& ptr )
  {
    --(*internal_counter);

    if(*internal_counter < 1)
    {
      delete internal_pointer;
      delete internal_counter;
    }

    internal_pointer = ptr.internal_pointer;
    internal_counter = ptr.internal_counter;
    (*internal_counter)++;
  }

И конструктор по умолчанию
Код

smrt_ptr()
{
  internal_pointer = NULL;
  internal_counter = new long int;
  *internal_counter = 0;
}

Большое спасибо.
PM MAIL   Вверх
borisbn
Дата 21.6.2011, 06:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 21
Всего: 135



Почему оператор == не констовый?

Это сообщение отредактировал(а) borisbn - 21.6.2011, 06:37


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
azesmcar
Дата 21.6.2011, 08:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Hassel

Дублирование кода говорит об очевидном

Цитата(Hassel @  20.6.2011,  22:02 Найти цитируемый пост)
    --(*internal_counter);
    if(*internal_counter < 1)
    {
      delete internal_pointer;
      delete internal_counter;
    }

пора выделять в отдельную функцию.
конструктор копирования содержит ошибки. Как минимум декрементирование неинициализорванного счетчика, ну и не работает как должен
Цитата(Hassel @  20.6.2011,  22:02 Найти цитируемый пост)
--(*internal_counter);

и константные функции так и не появились.
PM   Вверх
bsa
Дата 21.6.2011, 13:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Оператор присваивания делается так:
Код
smrt_ptr& operator=(const smrt_ptr &other)
{
   smrt_ptr(other).swap(*this);
   return *this;
}

void swap(smrt_ptr &other)
{
   T *p = internal_pointer;
   internal_pointer = other.internal_pointer;
   other.internal_pointer = p;
   long *i  = internal_counter;
   internal_counter = other.internal_counter;
   other.internal_counter = i;
}


Это сообщение отредактировал(а) bsa - 21.6.2011, 13:30
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0512 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.