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

Поиск:

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


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 16.4.2006

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



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

В итоге, получился такой код. Но как то хочется его допилить и сделать более элегантным, есть идеи? smile

Код

#include <iostream>
using namespace std;

class ObjectA
{
  public:
    ObjectA() {}
    virtual int x() const { return 1; }
    virtual ObjectA *clone() const { return new ObjectA; }
};

class ObjectB: public ObjectA
{
  public:
    ObjectB() {}
    int y() const { return 2; }
    virtual ObjectB *clone() const { return new ObjectB; }
};

template <typename ObjectT>
class SmartPointer
{
  public:
    SmartPointer()
      :obj_(0), use_(new size_t(1)) {}

    explicit SmartPointer(ObjectT *obj)
      :obj_(obj), use_(new size_t(1)) {}

    SmartPointer(const ObjectT &obj)
      :obj_(obj.clone()), use_(new size_t(1)) {}

    SmartPointer(const SmartPointer &other) {
      copy(other);
      incrUse();
    }

    virtual ~SmartPointer() {
      decrUse();
    }

    SmartPointer &operator=(const SmartPointer &other) {
      other.incrUse();
      decrUse();
      copy(other);
      return *this;
    }

    const ObjectT *operator->() const {
      if(obj_)
        return obj_;
    }

    const ObjectT &operator*() const {
      if(obj_)
        return *obj_;
    }

  protected:
    ObjectT *obj() const {
      return obj_;
    }

  private:
    virtual void copy(const SmartPointer &other) {
      obj_ = other.obj_;
      use_ = other.use_;
    }

    void clean() {
      if(obj_)
      {
        delete obj_;
        obj_ = 0;
      }
      if(use_)
      {
        delete use_;
        use_ = 0;
      }
    }

    void incrUse() const {
      ++*use_;
    }

    void decrUse() {
      if(--*use_ == 0)
        clean();
    }

    ObjectT *obj_;
    mutable size_t *use_;
};

template <typename BaseT, typename DescendantT>
class SmartPointerDescendant: public SmartPointer<BaseT> {
  public:
    SmartPointerDescendant()
      :SmartPointer<BaseT>() {}
    SmartPointerDescendant(const DescendantT &obj)
      :SmartPointer<BaseT>(obj) {}
    explicit SmartPointerDescendant(DescendantT *obj)
      :SmartPointer<BaseT>(obj) {}
    SmartPointerDescendant(const SmartPointer<BaseT> &other)
      :SmartPointer<BaseT>(other) {}
    SmartPointerDescendant(const SmartPointerDescendant &other)
      :SmartPointer<BaseT>(other) {}

    const DescendantT *operator->() const {
      if(DescendantT *obj = static_cast<DescendantT *>(SmartPointer<BaseT>::obj()))
        return obj;
    }

    const DescendantT &operator*() const {
      if(DescendantT *obj = static_cast<DescendantT *>(SmartPointer<BaseT>::obj()))
        return *obj;
    }

  private:
    class Base: public SmartPointer<BaseT> {};

};

int main()
{
  //SmartPointerDescendant<ObjectA, ObjectB> b( (ObjectB()) );
  SmartPointerDescendant<ObjectA, ObjectB> b( new ObjectB );
  SmartPointer<ObjectA> a = b;

  cout<<b->x()<<endl;
  cout<<a->x()<<endl;
  cout<<static_cast< SmartPointerDescendant<ObjectA, ObjectB> >(a)->y()<<endl;
}


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


uploading...
****


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

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



Лучше не выдумывай велосипеды а подключи boost, проблем с таким smartPointer-ом потом не оберешься. Аппетит приходит во время еды, подключишь boost и сразу появятся другие функции, которые понадобяться. Там много полезного. 

Просто пару замечаний, которые сразу попались на глаза, не вдавался в подробности
1. Зачем нужно наследование?
Код

    const ObjectT *operator->() const {
      if(obj_)
        return obj_;
    }

2. Где функция для НЕ константного указателя? Так выходит что можно вызывать только константные функции класса.
3. Что возвращяет функция в случае else? Ничего, что будет? Неясно.
4. mutable какой-то явно тут не нужный...

в общем хочешь хороший smart pointer - используй boost, ну или скопируй оттуда в крайнем случае.


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


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 16.4.2006

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



Цитата
1. Зачем нужно наследование?

чтобы могли сделать так:
SmartPointer<ObjectA> a = b;
если есть альтернативное решение, привести один класс умного указателя к другому (для случая, когда упровляемые объекты наследуются один от другого), оч интересно послушать

Цитата
2. Где функция для НЕ константного указателя? Так выходит что можно вызывать только константные функции класса.

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

Цитата
3. Что возвращяет функция в случае else? Ничего, что будет? Неясно.

Это интересный вопрос smile пока что я думаю, единственно верный ход - выбрасывать исключение

Цитата
4. mutable какой-то явно тут не нужный...

можно и без него

Это сообщение отредактировал(а) fear - 24.2.2010, 21:27
PM MAIL   Вверх
azesmcar
Дата 24.2.2010, 21:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


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

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



fear

Честно говоря сейчас лень смотреть, я по вечерам ленивый..если не будет ответов утром с работы подробно прокомментирую.
PM   Вверх
fear
Дата 24.2.2010, 23:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 16.4.2006

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



Цитата(azesmcar @ 24.2.2010,  21:31)
fear
Честно говоря сейчас лень смотреть, я по вечерам ленивый..если не будет ответов утром с работы подробно прокомментирую.

участие в обсуждении темы по желанию, любое мнение ценно smile
PM MAIL   Вверх
andrew_121
Дата 24.2.2010, 23:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


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

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



Цитата(fear @  24.2.2010,  23:02 Найти цитируемый пост)
участие в обсуждении темы по желанию

установи нормальный компилятор, тогда буст тягать не придется. т.к. все уже встроено. и смарт поинтеры в том числе.


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
fear
Дата 24.2.2010, 23:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 16.4.2006

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



Цитата(andrew_121 @ 24.2.2010,  23:15)
установи нормальный компилятор, тогда буст тягать не придется. т.к. все уже встроено. и смарт поинтеры в том числе.

это что за компиляторы такие, в которых все встроено? smile
PM MAIL   Вверх
andrew_121
Дата 24.2.2010, 23:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


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

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



gcc-4.4.3 и выше. а gcc-4.4.5 уже и лямбда поддерживает. и extern template.

Добавлено через 1 минуту и 4 секунды
под вендавз это mingw32 зовется.

Добавлено через 2 минуты и 1 секунду
а вообще тут все описано: http://gcc.gnu.org/gcc-4.5/cxx0x_status.html


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
fear
Дата 24.2.2010, 23:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 16.4.2006

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



Цитата
gcc-4.4.3 и выше. а gcc-4.4.5 уже и лямбда поддерживает. и extern template.

лямбда функции это хорошо, а вот умных указателей я не увидел, можно примерчик? да и сыровата версия 4.4.3 пока еще, не говоря уже о 4.4.5.

Цитата
под вендавз это mingw32 зовется.

спасибо конечно, но виндовс мне не нада, упоси smile

Это сообщение отредактировал(а) fear - 24.2.2010, 23:42
PM MAIL   Вверх
andrew_121
Дата 24.2.2010, 23:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


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

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



Цитата(fear @  24.2.2010,  23:42 Найти цитируемый пост)
да и сыровата версия 4.4.3

это релиз smile 

Цитата(fear @  24.2.2010,  23:42 Найти цитируемый пост)
не говоря уже о 4.4.5.

упс, опечатался. gcc-4.5.0. да, сыровата. но тесты все проходит. все что я этой версией компилил, работает без глюков.

Цитата(fear @  24.2.2010,  23:42 Найти цитируемый пост)
можно примерчик?

Код

#include <memory>

std::string my_mega_reader(std::shared_ptr<FILE> file) {
   ....
}

int main() {
   std::shared_ptr<FILE> file(fopen("", ""));
   return 0;
}


Добавлено через 2 минуты и 28 секунд
Цитата(fear @  24.2.2010,  23:42 Найти цитируемый пост)
спасибо конечно, но виндовс мне не нада, упоси

тогда не понятно в чем проблема? смарт поинтеры появились начиная с версии 4.4.0


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
fear
Дата 25.2.2010, 00:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 16.4.2006

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



Цитата
это релиз smile 

ага, но свежий очень

Цитата
std::shared_ptr<FILE> file(fopen("", ""));

я что-то и не заметил, над посматреть

Цитата
тогда не понятно в чем проблема? смарт поинтеры появились начиная с версии 4.4.0

лень проблема smile я счас под macos тут в портах 4.2.1 самая свежая; завел убунту под вбоксом, ставлю 4.4.1 из репозитория smile

Это сообщение отредактировал(а) fear - 25.2.2010, 00:17
PM MAIL   Вверх
andrew_121
Дата 25.2.2010, 00:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


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

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



Цитата(fear @  25.2.2010,  00:16 Найти цитируемый пост)
я счас под macos тут в портах 4.2.1

да, у них с этим туго. я недели две назад пытался 4.4.2 установить. дня два бился. не сумел :(

Цитата(fear @  25.2.2010,  00:16 Найти цитируемый пост)
завел убунту под вбоксом, ставлю 4.4.1 из репозитория

да только эта и есть.

остальные версии нужно с сорцов ставить. но там сложностей не возникает.


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
fear
Дата 25.2.2010, 00:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 16.4.2006

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



Цитата
остальные версии нужно с сорцов ставить. но там сложностей не возникает.

сложности появяться когда пересобирать все будешь под новую версию smile
PM MAIL   Вверх
andrew_121
Дата 25.2.2010, 00:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


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

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



Цитата(fear @  25.2.2010,  00:35 Найти цитируемый пост)
сложности появяться когда пересобирать все будешь под новую версию

никаких сложностей. разве что варнингов больше. ибо проверка типов более строгая.
самый стандартный варнинг:
Код

char* str = "str"; // const to non const



--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
bsa
Дата 25.2.2010, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



fear, имей в виду, что andrew_121 говорит про фичи, которые будут в БУДУЩЕМ стандарте С++, но которые поддерживаются GCC в экспериментальном режиме (нужно указывать специальный ключ).
Пока стандарт не принят, лучше использовать старый добрый boost.
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

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

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


 




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


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

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