Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.05.2012, 22:07   #1
Aldegid
 
Регистрация: 30.12.2011
Сообщений: 6
По умолчанию вектор указателей на экземпляры класса

Здравствуйте.

Опуская предысторию, хочу написать класс на основе stl::vector, который бы хранил указатели на классы, сами ими владел, оперировал, освобождал.

Сейчас вот пишу и думаю, может, я и не прав, может не нужно вектора указателей, может можно просто вектор экземпляров класса. Ну просветите мне мозги, если я переусложняю.

Так вот. (чтобы не перегружать пост - даю ссылочки на код).
Первый вариант
Второй вариант
И в конце концов Крашеный кубик-рубик
Последний вариант решил проблему, но как-то... ну вы понимаете.

В общем any help will be appreciated
Aldegid вне форума Ответить с цитированием
Старый 04.05.2012, 00:10   #2
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

1. Мало мало косячно отнаследовался от стандартного вектора, зарубив львиную долю его функционала.

2. Если нужен "вектор указателей, контролирующий время жизни", достаточно использовать стандартный вектор сильных указателей. То бишь, никакие дополнительные самоделки для этого не нужны.
_Bers вне форума Ответить с цитированием
Старый 04.05.2012, 10:45   #3
Krok27
Форумчанин
 
Аватар для Krok27
 
Регистрация: 08.07.2010
Сообщений: 505
По умолчанию

3. Использовать модель включения, а не наследия.
Код:
template <class Т, class CONTAINER = std::vector<T*> >
class CPtrVector 
{
  private:
    CONTAINER elements;
  public:
    void push(const T* elem);
};
// Добавить элемент
template <class T, class CONTAINER>
  void CPtrVector<T, CONTAINER>::push(const T* elem)
  {
     elements.push_back(elem);
 }
или еще лучше, можно потом менять тип контейнера
Код:
template <class Т, template <class>  class CONTAINER = std::vector>
class CPtrVector 
{
   private:
       CONTAINER<T*> elements;
};

// Добавить элемент
template <class T, template <class>  class CONTAINER>
  void CPtrVector<T, CONTAINER>::push(const T* elem)
  {
     elements.push_back(elem);
 }
Знающий не говорит, говорящий не знает (С) Лао Цзы

Последний раз редактировалось Krok27; 04.05.2012 в 10:57.
Krok27 вне форума Ответить с цитированием
Старый 04.05.2012, 13:51   #4
Aldegid
 
Регистрация: 30.12.2011
Сообщений: 6
По умолчанию

Re: _Bers, Ваш вариант выглядит более... в общем более.

Правильно я понимаю, что рекомендуется использовать

Код:
template<class T> vector<shared_ptr<T>>
?

Кроме того, я хочу использовать подобную конструкцию много раз, и ее хорошо определить где-нибудь в одном месте. Но чтобы мало-мало не зарубать даже конструкторы придется делать
Код:
#define CSmartVector(T) vector<shared_ptr<T>>
потому что ведь нельзя же будет сделать с этим typedef, потому что, насколько я знаю шаблонные typedef'ы не допускаются?

Сейчас вот думаю, где там еще какие баги могут возникнуть...
Aldegid вне форума Ответить с цитированием
Старый 04.05.2012, 14:10   #5
Rififi
Старожил
 
Регистрация: 19.08.2009
Сообщений: 2,119
По умолчанию

Aldegid

То, что ты пытаешься в муках изобрести, называется boost:: ptr_vector<> oO

Последний раз редактировалось Rififi; 04.05.2012 в 14:13.
Rififi вне форума Ответить с цитированием
Старый 04.05.2012, 14:47   #6
Aldegid
 
Регистрация: 30.12.2011
Сообщений: 6
По умолчанию

Кроме того я задумался вообще вот над чем: а так ли мне нужны указатели. Может быть просто вектор объектов?
Неудобно только вставлять - каждый push_back лишние создание и удаление.
Причем тут еще зависит, содержит ли сам тип T указатели на тяжелые (большие по размеру) объекты... вообще содержит ли указатели.

Я так понимаю, раз я много раз написал

Код:
class SomeWrapperClass
{
   vector<SomeClass *> somefield;
};
а SomeClass может сам содержать указатели или, хуже того, другие вектора
Код:
class SomeClass
{
   SomeOtherClass *pointerField;
   vector<SomeReallyOtherClass *> someReallyOddField;
};
то мне нужно выработать какую-то общую политику, как поступать во всех случаях, чтобы не приходилось думать о каждом. Можете подскзать что-нибудь по этому поводу?
Aldegid вне форума Ответить с цитированием
Старый 04.05.2012, 14:57   #7
Aldegid
 
Регистрация: 30.12.2011
Сообщений: 6
По умолчанию

Цитата:
Сообщение от Rififi Посмотреть сообщение
Aldegid

То, что ты пытаешься в муках изобрести, называется boost:: ptr_vector<> oO
boost, говорите? ну ждите вопросов по boost. В прошлый раз мне не удалось его даже "сварить". Посмотрим, как получится "извлечь необходимое подмножество исходников с сохранением зависимостей" в этот раз.
Aldegid вне форума Ответить с цитированием
Старый 04.05.2012, 21:09   #8
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от Aldegid Посмотреть сообщение
Кроме того я задумался вообще вот над чем: а так ли мне нужны указатели. Может быть просто вектор объектов?
Неудобно только вставлять - каждый push_back лишние создание и удаление.
Причем тут еще зависит, содержит ли сам тип T указатели на тяжелые (большие по размеру) объекты... вообще содержит ли указатели.

Я так понимаю, раз я много раз написал

Код:
class SomeWrapperClass
{
   vector<SomeClass *> somefield;
};
а SomeClass может сам содержать указатели или, хуже того, другие вектора
Код:
class SomeClass
{
   SomeOtherClass *pointerField;
   vector<SomeReallyOtherClass *> someReallyOddField;
};
то мне нужно выработать какую-то общую политику, как поступать во всех случаях, чтобы не приходилось думать о каждом. Можете подскзать что-нибудь по этому поводу?
Каждый раз, когда ты добавляешь/удаляешь из вектора, он у тебя сжимается/расжимается.

При этом все элементы сдвигаются по вектору при помощи operator=

Если тебя парят потери производительности - смотри в сторону других контейнеров, а ещё лучше - пулов памяти. Если не парят - тогда вообще не майся дурью. Не нужно изобретать велосипед.
_Bers вне форума Ответить с цитированием
Старый 05.05.2012, 18:50   #9
Aldegid
 
Регистрация: 30.12.2011
Сообщений: 6
По умолчанию

Полчаса писал ответ и, как всегда бывает на кхм... в общем переписываю.

Вот такая ситуация
Код:
class SomeClass
{
   SomeInnerClass *pointer;
};

typedef vector<SomeClass *> TSomeClasses;

class SomeOuterClass
{
   TSomeClasses someClasses;
   /* куча других полей-значений, из-за которых не хочется писать конструктор копирования, тем более, что этот список может измениться */
public:
   SomeOuterClass( const SomeOuterClass &other ); // (1)
   ~SomeOuterClass(); // (2)
};
Я думаю все понятно. Если я скопирую SomeOuterClass конструктором копирования по умолчанию (не буду описывать (1)), то скопируется someClasses, а при удалении первого экземпляра SomeOuterClass честным SomeOuterClass::~SomeOuterClass экземпляры SomeClass будут удалены и я получу двойное удаление при удалении копии SomeOuterClass. Это классика.
Значит, мне нужно иметь такой
Код:
typedef vector_adapter<SomeClass *> TSomeClasses
, который бы при копировании копировал бы все свои экземпляры SomeClass. Ну да, и ещё нужно учитывать, что SomeClass может быть не в натуральном виде, а ещё обладать иерархией. Для этого думаю присобачить
Код:
class SomeClass
{
public:
   virtual SomeClass *Clone();
};
Вот и скажите, уважаемые _Bers и Rififi, подойдут ли мне boost:tr_vector или другие контейнеры или пулы памяти или мне все таки стоит дописать CPtrVector из Первого примера, тем более, что с тем, как написать итераторы я разобрался (кажется...). Ну хоть
Код:
#define PtrVectorIter(T) vector<T *>::iterator

Последний раз редактировалось Aldegid; 05.05.2012 в 18:58.
Aldegid вне форума Ответить с цитированием
Старый 06.05.2012, 01:15   #10
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Пока учишься - учись. Пробуй. Ошибайся.
Но если нужно для боевого кода - лучше пользовать профессиональные инструменты.
_Bers вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
вектор, состоящий из обьектов класса sinestro Visual C++ 3 20.04.2012 15:07
вектор объектов класса и алгоритмы РагнаР Общие вопросы C/C++ 3 10.04.2011 07:00
Вектор из callback'ов методов класса Gongled Общие вопросы C/C++ 7 05.01.2011 16:29
Все экземпляры класса russian-stalker Общие вопросы Delphi 6 21.08.2009 11:16
массив указателей на методы класса? cout Общие вопросы C/C++ 2 08.05.2008 09:43