Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Указатаеь на вектор векторов


Автор: Woo 14.4.2007, 09:53
привет

нормально ли так делать?

Код

const int X = 5, Y = 3;
...
vector<vector<bool> > *_boolVector = new vector<vector<bool> >( X, vector<bool>( Y, false ) );
...
delete _boolVector;

Автор: vinter 14.4.2007, 10:27
а зачем тебе это?
да и выглядит как-то убого.. smile 

Автор: dizzy1984 14.4.2007, 13:26
Ничего плохого не вижу.
Для работы с динамической памятью посоветовал бы еше добавить const auto_ptr, чтобы избежать возможных проблем с утечками памяти.
А для какой задачи это тебе нужно.
В стандартной библиотеке есть специальные контейнеры для булевых величин.

Автор: zkv 14.4.2007, 13:29
Цитата(dizzy1984 @  14.4.2007,  13:26 Найти цитируемый пост)
В стандартной библиотеке есть специальные контейнеры для булевых величин.

один из них как раз и есть vector<bool>  smile 
Цитата(dizzy1984 @  14.4.2007,  13:26 Найти цитируемый пост)
Ничего плохого не вижу.

плохо воспринимается smile

Автор: dizzy1984 14.4.2007, 13:55
Цитата(zkv @  14.4.2007,  13:29 Найти цитируемый пост)
плохо воспринимается 

Зато удобно используется.
Ну используй typedef.

Код

const int X = 5, Y = 3;    
typedef vector <bool> BOOLVECTOR;
typedef vector <BOOLVECTOR> BOOLMATRIX;
...    
BOOLMATRIX bm (X, BOOLVECTOR(Y, false))



Цитата(zkv @  14.4.2007,  13:29 Найти цитируемый пост)
один из них как оаз и есть vector<bool>   

 smile 
А точно, специализация.
Второй это bitset.

Автор: Fazil6 14.4.2007, 14:03
Цитата(dizzy1984 @  14.4.2007,  13:26 Найти цитируемый пост)
Ничего плохого не вижу.

на самом деле vector<bool> - плохо.
Нужно избегать vector<bool>. Это не контейнер STL и он не содержит bool....

В требованиях стандарта говорится, что если v контейнер объектов T , с оператором [] , то должно компиллится
Код

T *p = &v[0];

но с bool такая конструкция не скомпилится. vector<bool> - это псевдоконтейнер. 

Автор: Woo 15.4.2007, 00:07
спасибо,

меня еще немного напрягает
Код

delete _boolVector;


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

Код

#include <boost/numeric/ublas/matrix.hpp>

using namespace boost::numeric::ublas;
...
matrix<bool> *_mBool = new matrix<bool>(X, Y);
...
delete _mBool;



Автор: Fazil6 15.4.2007, 00:24
Цитата(Woo @  15.4.2007,  00:07 Найти цитируемый пост)
я думаю наверно лучше всего использовать

а чего не синхрофазотрон?

Автор: JackYF 16.4.2007, 16:10
Цитата(dizzy1984 @  14.4.2007,  13:26 Найти цитируемый пост)
const auto_ptr,


Имхо - нафиг. Слишком много граблей будет да и читабельность...

Цитата(Fazil6 @  15.4.2007,  00:24 Найти цитируемый пост)
а чего не синхрофазотрон? 

действительно...

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

По начальному вопросу - кроме громоздкого объявления, проблем не вижу. Можно, как предлагали, сделать typedef разве что.

Автор: dizzy1984 16.4.2007, 19:19
Цитата(JackYF @  16.4.2007,  16:10 Найти цитируемый пост)
Имхо - нафиг. Слишком много граблей будет да и читабельность...

Обоснуй, пожалуйста.
В c++ есть по крайней мере 2 бича - приведение типов и проблемы с памятью (нет автоматической сборки, выход за пределы массива). Существуют даже языки, специально сделанные для устранения этих проблем (ну и для кое-чего другого), например, java.
О каких граблях ты говоришь. Если о передачи владельца, то эти проблемы снимает const. Если о читабельности - есть typedef smile ,
отступы, комментарии. Мне кажется читабельность менее важна чем стабильная работа программы (отсутствие утечек памяти). Или ты имеешь в виду другой smart pointer вместо этого.
Я слышал уже такое мнение и мне интересны его причины.

Автор: JackYF 16.4.2007, 21:27
Цитата(dizzy1984 @  16.4.2007,  19:19 Найти цитируемый пост)
Обоснуй, пожалуйста.


Ну, во-первых, если мне понадобятся смарт-поинтеры, то я первую очередь посмотрю на boost::shared_ptr.

Про грабли с std::auto_ptr - вот не вспомню сейчас, где и у кого читал, но использование std::auto_ptr чревато очень многими граблями. Я тогда прочитал про эти грабли и для себя поставил галочку - "да, грабли опасные, auto_ptr "ф топку".
Например, передача такого ptr в функцию. И как раз const эти проблемы не снимает. Их снимает частично const&. Да и то там...

Но это далеко не все. Если как-нибудь пороюсь, то найду дли-и-инный список, почему потенциально плохо юзать std::auto_ptr.
Сейчас уже не вспомню все грабли.

Добавлено через 1 минуту и 39 секунд
Цитата(dizzy1984 @  16.4.2007,  19:19 Найти цитируемый пост)
Если о читабельности - есть typedef smile


Да, кстати, насчет typedef... А приведи-ка пример, как ты его применишь в данном случае.

Автор: Fazil6 16.4.2007, 21:46
Цитата(JackYF @  16.4.2007,  21:27 Найти цитируемый пост)
std::auto_ptr

нельзя хранить это в контейнерах STL. Семантика копирования у std::auto_ptr спецефическая. По стандарту это даже компиллится не должно.

Цитата(dizzy1984 @  16.4.2007,  19:19 Найти цитируемый пост)
Мне кажется читабельность менее важна чем стабильная работа программы

не менее важна. Сопровождение длится намного дольше чем разработка

Автор: dizzy1984 17.4.2007, 06:04
Цитата(Fazil6 @  16.4.2007,  21:46 Найти цитируемый пост)
нельзя хранить это в контейнерах STL

Это и не понадобится, stl контейнеры сами работают с памятью, auto_ptr там не причем.
Цитата(Fazil6 @  16.4.2007,  21:46 Найти цитируемый пост)
 Семантика копирования у std::auto_ptr спецефическая

auto_ptr p1,p2;
выражение p1=p2 приводит к модификации правой части, в этом и выражается специфика.
здесь работает механизм передачи владельца, он призван ограничить количество указателей на
1н объект.
Когда такое поведение нежелательно (с трудом представляю себе когда оно может быть желательно)
ставят модификатор const. При передаче в функцию в ее сигнатуре объявляют как const &.
Другими словами применение const auto_ptr при объявлении указателей на объект и 
const auto_ptr & при объявлении в функции должно гарантировать отстствие любых "граблей".

Цитата(Fazil6 @  16.4.2007,  21:46 Найти цитируемый пост)
не менее важна. Сопровождение длится намного дольше чем разработка

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


JackYF, извини, но в твоем ответе нет ни одной причины почему не стоит его применять.
Про  boost::shared_ptr ничего не скажу, потому что этой библиотекой не пользовался.

ну на счет typedef'а. что-то он слишком ного внимания получает  smile 

typdef std::auto_ptr<ClassA> CLASSAAUTOPTR;
CLASSAAUTOPTR ptr(new ClassA);



Автор: Daevaorn 17.4.2007, 07:06
Цитата(dizzy1984 @  17.4.2007,  07:04 Найти цитируемый пост)
Это и не понадобится, stl контейнеры сами работают с памятью, auto_ptr там не причем.

но auto_ptr нельзя положить в контейнер.

Автор: Fazil6 17.4.2007, 12:05
Цитата(dizzy1984 @  17.4.2007,  06:04 Найти цитируемый пост)
Нууу, если твоя программа работает в 40% ситуаций, сопровождать ее будет сложнее, чем, скажем, покопаться в не столькосамопонятном коде раз в месяц.

ага... опять 25...
Кто Вам сказал, что правильность работы программы и читабельность ее - это вещи взаимоисключающие ? Код пишется в первую очередь не для компиллятора, а для человека, который будет читать его

Автор: dizzy1984 17.4.2007, 12:23
Я так понимаю он используется для единичных объектов.
Какой смысл его класть в контейнер, если там и без него работает автоматическая отчистка памяти.

Автор: Fazil6 17.4.2007, 12:29
Цитата(dizzy1984 @  17.4.2007,  12:23 Найти цитируемый пост)
Какой смысл его класть в контейнер, если там и без него работает автоматическая отчистка памяти.

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

Автор: JackYF 17.4.2007, 15:02
Цитата(dizzy1984 @  17.4.2007,  06:04 Найти цитируемый пост)
CLASSAAUTOPTR


Мдя. Очень читабельно. И главное, сразу все ясно. А если, например, требуется завернуть шаблонный класс?
В шаблонной функции даже typedef не сделаешь.
А большими буквами делают разве что макросы. Все, кроме MS. Вот от таких вот LPSZ, HUID и более длинных аббревиатур в uppercase
уйти сразу хочется и забыть про такой код.

Цитата(Daevaorn @  17.4.2007,  07:06 Найти цитируемый пост)
но auto_ptr нельзя положить в контейнер. 

Вот! Человек дело говорит. Ты что, указатели никогда в контейнер STL не ложил?



Цитата(dizzy1984 @  17.4.2007,  06:04 Найти цитируемый пост)
Нууу, если твоя программа работает в 40% ситуаций

40% - это не вообще работающая программа. smile


Цитата(dizzy1984 @  17.4.2007,  06:04 Найти цитируемый пост)
JackYF, извини, но в твоем ответе нет ни одной причины почему не стоит его применять.

Я не намерен кого-либо переубеждать. Найду как-нибудь книжку или статью, там, где это по полочкам расписано - в личку или в тему выложу.
Для себя я галку "не применять" поставил. Хочешь - пользуйся, на здоровье.

Цитата(dizzy1984 @  17.4.2007,  06:04 Найти цитируемый пост)
выражение p1=p2 приводит к модификации правой части, в этом и выражается специфика.

Вот. Эта специфика противоречит естественной специфике указателей. Еще одна грабля, если за этим не следить жестко.
Объявили в начале функции два объекта "типа указателя"... А потом в середине присвоили чему-то. Ведь это по идее должен был быть указатель... Вот тут-то грабли и могут вылезть.
Так мне легче проследить удаление всех объектов, над которыми я сделал new.

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

Автор: dizzy1984 17.4.2007, 17:08
============================
Святая инквизиция, ведьма и auto_ptr.
============================

Все совпадения с реальными людьми случайны, даже если на то не похоже.



Темный зал...
По стенам бегают отсветы факелов...
Судья : сегодня мы собрались здесь, чтобы судить самую страшную, самую жуткую и злую ведьму. Она 
совершила то, что многие из нас не могли даже представить... Она лечила детей с помощью auto_ptr.
Реплики с мест : не может быть, какой ужас!!
Судья : да, дамы и господа, увы это правда.
В зал вводят ведьму. Видно сгорбленную фигуру под темным капюшоном.
Духовный отец1 : ведьма, признаешь ли ты, что это принадлежит тебе. Протягивает ворох листков.
Ведьма : Да, это мои рецепты, по ним я лечила детей.
Духовный отец2 берет несколько листков.
Духовный отец2 : Что я вижу, тут ты писала названия трав заглавными буквами.
Ведьма : Да, так мне легче отличить одни травы от других.
Духовный отец2 : Это совершенно нечитабельно, ничего не ясно. А как же вы запишете можжевельник, сухой яр и корень мондрагоры?
Ведьма : Точно так же, просто мне потребуется больше букв.
Духовный отец1 : Чушь! И ты это знаешь, так поступали только давным-давно святые отцы-миссионеры в Ватикане, но уже давно это запрещено под страхом смертной казни. Каждый раз как я вижу такой рецепт мне сразу хочется уйти и забыть про него.
Судья : Вы понимаете, что ваши рецепты сложно прочитать? Что вы скажете в свое оправдание?
Ведьма : Но ведь я лечила детей и ни один не умер.
Судья : Мы здесь говорим не о здоровье детей, мы должны в первую очередь думать о беспорочности 
нашего ремесла, ремесла лекарей. Если ребенок умер - на то воля господа. Пути его неисповедимы.
Встает женщина в кокшнике и кричит со злобой : auto_ptr даже нельзя положить в контейнер.
Судья : Вот! Дело говорит верная сестра господа нашего. Ты что, мерзкая ведьма указатели никогда в 
контейнер STL не ложила?
Ведьма : Нет я всегда обходилась обычными объектами. Скажите, чем плох auto_prt? В чем я виновата?
Судья : Я не намерен тебе что-либо объяснять. Я хорошо знаю святое писание и там сказано что 
применять можно только boost::shared_ptr, особенно, когда лечишь детей. Я могу достать его(св. 
писание) в любой момент, только надо найти нужную полку.
Духовный отец1 громко читает один из листков ведьмы: выражение p1=p2 приводит к модификации правой части, в этом и выражается специфика...
У судьи наливается краской лицо.
Судья : Вот! Вот! Это противоречит самому естеству человеческому, самой сути указателей! Это большая проблема...
Ведьма : в рецепте чуть ниже написано, что это поведение снимается применением модификатора const.
Судья не обращает внимание на ведьму и продолжает : за ней надо четко следить.
Судья постепенно приходит в себя, взгляд его становится осмысленным. Он смотрит на ведьму.
Судья : даже если я забуду освободить память по указателю, это, конечно, не хорошо, но ребенок 
выздоровеет. Конечно, если он часто будет применять зелье, то потеряет руку, может даже обе, но 
будет продолжать жить. А вот в случае с auto_ptr - я не уверен.
Духовный отец1 : Кто за высшую меру наказания - сожжение на костре.
Все присутствующие в зале поднимают руки.
Духовный отец1 : Единогласно! Стража! Увести ее.
2 Рослых стражника утаскивают сопротивляющуюся ведьму.

Если серьезно.
Цитата(JackYF @  17.4.2007,  15:02 Найти цитируемый пост)
Вот. Эта специфика противоречит естественной 
специфике указателей. Еще одна грабля, если за этим не следить жестко.

Я уже говорил модификатор const решит эту проблему на этапе компиляции.
Цитата(JackYF @  17.4.2007,  15:02 Найти цитируемый пост)
Я не намерен кого-либо переубеждать. Найду как-нибудь книжку или статью

Я думаю на форуме лучше оперировать фактами и переубеждать чем просто высказывать неизвестно на чем основанные мнения.
Цитата(JackYF @  17.4.2007,  15:02 Найти цитируемый пост)
А большими буквами делают разве что макросы. 

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

Fazil6, мы говорим об одном и том же разными словами.

Автор: Earnest 17.4.2007, 17:30
dizzy1984, смешно, но неправильно.
Цитата(dizzy1984 @  17.4.2007,  18:08 Найти цитируемый пост)
Я уже говорил модификатор const решит эту проблему на этапе компиляции

Только в твоем коде.  А в коде стандартной библиотеки? Просто не скомпилируется.
Например, создаем вектор из нескольких авто-птэров. Потом добавляем еще один.
И допустим, это требует перераспределения памяти. Что получится в итоге? А как повезет. Но совершенно не то, на что ты расчитываешь. Это если бы скомпилировалось. Но не должно, и слава богу.

Кстати, с "просто" указателями, конечно, скомпилируется. Но вектор перестанет быть полноценным вектором (если все указатели динамические и они же являются владельцами выделенной памяти). В смысле, не все операции будут работать. Да, конечно, можно любой pop или resize сопровождать оператором delete.
Но угадай, что получится, если скажем вызвать стандартный алгоритм std::remove_if?
Отработает, конечно, но в результате останется выделенная память, на которую больше ничего не указывает.
И так со многими алгоритмами. STL предполагает, что объекты в контейнерах имеют корректную семантику копирования и присваивания. 

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

Автор: Daevaorn 17.4.2007, 17:30
Цитата(dizzy1984 @  17.4.2007,  18:08 Найти цитируемый пост)
Я уже говорил модификатор const решит эту проблему на этапе компиляции.

нет, проблему решает boost::scoped_ptr, у которого семантика копирования запрещена. Все махинации с std::auto_ptr потенциальные грабли. О чем тебе JackYF уже давно пытается сказать. 

Автор: JackYF 17.4.2007, 17:42
Цитата(dizzy1984 @  17.4.2007,  17:08 Найти цитируемый пост)
Но ведь я лечила детей и ни один не умер.

А вот тут поподробнее. Использовал где-то в своих кодах std::auto_ptr? В функциях длиннее 10-12 строк?

Цитата(dizzy1984 @  17.4.2007,  17:08 Найти цитируемый пост)
Конечно, если он часто будет применять зелье, то потеряет руку, может даже обе, но 
будет продолжать жить


А тут ребенок ничего не потеряет. За ним просто останется неубранный мусор местами, который уберет не сам ребенок, а уборщица в конце дня. smile

Цитата(dizzy1984 @  17.4.2007,  17:08 Найти цитируемый пост)
Все совпадения с реальными людьми случайны

Ага. Ведь к объективной реальности по затрагиваемому вопросу данная повесть имеет мало отношения smile.

Автор: dizzy1984 17.4.2007, 18:51
Ну что ж очень приятно, что тема привлекла столько внимания.
Как все таки иногда бывает полезно рассказать совершенно не относящуюся к теме беседы историю.

Цитата(Earnest @  17.4.2007,  17:30 Найти цитируемый пост)
dizzy1984, смешно, но неправильно.

Напомню, что основной вопрос который здесь обсуждается - можно ли так построить работу с классом auto_ptr, чтобы не было мистических "потенциальных граблей", про которые все слышали, но никто не сталкивался.
Что неправильно - не согласен. Правильно.
Буду приводить цитаты из книжки C++ Standart Library, The: A Tutorial and Reference.

Цитата(Earnest @  17.4.2007,  17:30 Найти цитируемый пост)
Только в твоем коде.  А в коде стандартной библиотеки? Просто не скомпилируется.

Абсолютно не понял.

Цитата(Earnest @  17.4.2007,  17:30 Найти цитируемый пост)
Например, создаем вектор из нескольких авто-птэров

auto_ptr не был спроектирован для того чтобы его клали в stl контейнер. Это задумано изначально.

Цитата

4.2.4 Misusing auto_ptrs
...
auto_ptrs don't meet the requirements for container elements.

An auto_ptr does not meet one of the most fundamental requirements for elements of standard containers. That is, after a copy or an assignment of an auto_ptr, source and sink are not equivalent. In fact, when an auto_ptr is assigned or copied, the source auto_ptr gets modified because it transfers its value rather than copying it. So you should not use an auto_ptr as an element of a standard container. Fortunately, the design of the language and library prevents this misuse from compiling in a standard-conforming environment.

Поэтому и рассуждать про это бессмысленно.
Цитата(Earnest @  17.4.2007,  17:30 Найти цитируемый пост)
Это если бы скомпилировалось

Вижу вы сами это понимаете.
Далее вы, по-видимому, перечисляете варианты того, как можно положить в контейнер указатель и выделять с его помощью память... ну вы и сами приходите к тому, что это никогда не нужно.

Цитата(Earnest @  17.4.2007,  17:30 Найти цитируемый пост)
 Контейнеры\алгоритмы для того и созданы, чтобы не думать
о деталях

Тезисы. auto_ptr не нужно класть в контейнер.
В контейнерные классы вообще никогда не нужно класть указатели, т.к контейнеры сами управляют распределением памяти и на это даже можно повлиять.


Цитата(Daevaorn @  17.4.2007,  17:30 Найти цитируемый пост)
 Все махинации с std::auto_ptr потенциальные грабли. О чем тебе JackYF уже давно пытается сказать

Ни JackYF, ни ты не правы.

Очередная цитата из книжки

Цитата

Fortunately, there was a late design decision that made auto_ptrs less dangerous. By some tricky implementation techniques, transfer of ownership is not possible with constant references. In fact, you can't change the ownership of any constant auto_ptr:

      
   const std::auto_ptr<int> p(new int);
   *p = 42;         //change value to which p refers
   bad_print(p);    //COMPILE-TIME ERROR
   *p = 18;         //OK




Цитата

You can't change the ownership of a constant auto_ptr;


Автор сам говорит, что auto_ptr без const применять нельзя. Конечно, жутковато, но это stl.
Цитата

Unfortunately, sometimes the misuse of an auto_ptr works. Regarding this, using nonconstant auto_ptrs is no safer than using ordinary pointers. You might call it luck if the misuse doesn't result in a crash, but in fact you are unlucky because you don't realize that you made a mistake.



Цитата(JackYF @  17.4.2007,  17:42 Найти цитируемый пост)
А вот тут поподробнее. Использовал где-то в своих кодах std::auto_ptr? В функциях длиннее 10-12 строк?

Я использую их в качестве полей классов. Это, похоже, единственное применение auto_ptr

Защитная цитата
Цитата

4.2.3 auto_ptrs as Members
By using auto_ptrs within a class you can also avoid resource leaks. If you use an auto_ptr instead of an ordinary pointer, you no longer need a destructor because the object gets deleted with the deletion of the member. In addition, an auto_ptr helps to avoid resource leaks that are caused by exceptions that are thrown during the initialization of an object.

Т.е - auto_ptr есть ни что иное как панацея от проблем с динамической памятью для поля класса в c++.

Незащищенный вариант
Цитата

 class ClassB {
     private:
       ClassA* ptr1;                 //pointer members
       ClassA* ptr2;
     public:


Защищенный вариант
Цитата

 class ClassB {
     private:
       const std::auto_ptr<ClassA> ptr1;         //auto_ptr members
       const std::auto_ptr<ClassA> ptr2;
     public:

И возможно здесь и кроется разгадка всего нашего спора.
Возможно, вы думали о каком-то другом применении auto_ptr? По-другому я его применять не собираюсь.

Цитата(JackYF @  17.4.2007,  17:42 Найти цитируемый пост)
А тут ребенок ничего не потеряет

Если применять const auto_ptr для члена класса, который не является массивом, то да память освободится в любом случае.


Цитата(JackYF @  17.4.2007,  17:42 Найти цитируемый пост)
Ага. Ведь к объективной реальности по затрагиваемому вопросу данная повесть имеет мало отношения

Несомненно, ведь я такой фантазер  smile 

Чисто для очистки совести приведу остальные misusing для auto_ptr

Цитата

auto_ptrs cannot share ownership.

An auto_ptr must not refer to an object that is owned by another auto_ptr (or other object). Otherwise, if the first pointer deletes the object, the other pointer suddenly refers to a destroyed object, and any further read or write access may result in disaster.

auto_ptrs are not provided for arrays.

An auto_ptr is not allowed to refer to arrays. This is because an auto_ptr calls delete instead of delete [] for the object it owns. Note that there is no equivalent class in the C++ standard library that has the auto_ptr semantics for arrays. Instead, the library provides several container classes to handle collections of data (see Chapter 5).

auto_ptrs are not "universal smart pointers."

An auto_ptr is not designed to solve other problems for which smart pointers might be useful. In particular, they are not pointers for reference counting. (Pointers for reference counting ensure that an object gets deleted only if the last of several smart pointers that refer to that object gets destroyed.)


Автор: Daevaorn 17.4.2007, 19:04
dizzy1984, говорят, что "краткость сестра таланта". Не слышал об этом?
Цитата(dizzy1984 @  17.4.2007,  19:51 Найти цитируемый пост)
Я использую их в качестве полей классов. Это, похоже, единственное применение auto_ptr

Я плакал.
Цитата(dizzy1984 @  17.4.2007,  19:51 Найти цитируемый пост)
Т.е - auto_ptr есть ни что иное как панацея от проблем с динамической памятью для поля класса в c++.

ааа. скорую мне. 
Меня бы уволили за такое применение std::auto_ptr
Цитата(dizzy1984 @  17.4.2007,  19:51 Найти цитируемый пост)
В контейнерные классы вообще никогда не нужно класть указатели, т.к контейнеры сами управляют распределением памяти и на это даже можно повлиять.

ааа.спосите мой мозг.
Цитата(dizzy1984 @  17.4.2007,  19:51 Найти цитируемый пост)
Очередная цитата из книжки

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

Автор: JackYF 17.4.2007, 19:08
Цитата(dizzy1984 @  17.4.2007,  18:51 Найти цитируемый пост)
class ClassB {
     private:
       ClassA* ptr1;                 //pointer members
       ClassA* ptr2;
     public:


operator=, например... выдержка.

Код

...
delete ptr1;
ptr1 = new ClassA(*ptr3);
...


Твои действия в этом случае с помощью std::auto_ptr?

Автор: Earnest 17.4.2007, 19:24
Хм, мне показалось, что речь с самого начала шла об использовании auto_ptr в контейнерах...
Особенно в твоей леденящей истории:
Цитата(dizzy1984 @  17.4.2007,  18:08 Найти цитируемый пост)
 Ты что, мерзкая ведьма указатели никогда в 
контейнер STL не ложила?

Но если нет, то и ладно.
А сам по себе auto_ptr, использованный правильным образом (т.е. как отдельная автоматическая переменная), опасен разве что граблями с присваиванием... о чем уже писали. 
Однако, если следовать Мерфи, на валяющиеся грабли рано или поздно кто-нибудь наступит.

Цитата(Daevaorn @  17.4.2007,  20:04 Найти цитируемый пост)

Цитата(dizzy1984 @  17.4.2007,  19:51 )
Я использую их в качестве полей классов. Это, похоже, единственное применение auto_ptr
Я плакал.

Да уж. Не только не единственное, но и не особо удачное применение.

В общем, нормальный указатель с эксклюзивным владением (бустовский или самописный), не имеющий конструктора копирования, абсолютно заменяет auto_ptr там, где auto_ptr безопасен, и не дает себя использовать там, где это опасно.

Короче, единственное оправдание в его использовании - это то, что в stl другого нет. Но это не оправдание. smile 
И, кстати, насчет правильности кода. Кроме "правильный" или "неправильный" код еще может быть "вонючим".
Вот auto_ptr именно такой. Работает вроде. Но попахивает...

Автор: dizzy1984 17.4.2007, 19:57
Цитата(Daevaorn @  17.4.2007,  19:04 Найти цитируемый пост)
ааа. скорую мне. 
Меня бы уволили за такое применение std::auto_ptr

Какое(ие) применение будет удачнее?


Цитата(JackYF @  17.4.2007,  19:08 Найти цитируемый пост)
Твои действия в этом случае с помощью std::auto_ptr?

Я так понял, что почва использования неконстантного auto_ptr очень шаткая из-за его механизма передачи владельца. Поэтому я бы использовал другой умный указатель для твоего примера

Автор: JackYF 17.4.2007, 20:52
Цитата(dizzy1984 @  17.4.2007,  19:57 Найти цитируемый пост)
Я так понял, что почва использования неконстантного auto_ptr очень шаткая из-за его механизма передачи владельца. Поэтому я бы использовал другой умный указатель для твоего примера 


О чем и речь. Не раз указатели в полях моих классов ведут себя именно таким образом. Именно так я писал копирования (там, где это было быстро и удобно), и всего лишь один-единственный раз не забывал про деструктор. Прописать там одну строчку - не проблема, имхо.
Это не стоит выделения pointer'ов в smart-pointer. Это из пушки по воробьям.

Цитата(dizzy1984 @  17.4.2007,  19:57 Найти цитируемый пост)
Какое(ие) применение будет удачнее?

Здесь - даже не знаю. Мое имхо по этому вопросу - я обхожусь без них, а вообще - разве что в локальных функциях, там больше риск забыть удалитьsmile освободить память."

Автор: Earnest 17.4.2007, 21:32
Цитата(JackYF @  17.4.2007,  21:52 Найти цитируемый пост)
Это не стоит выделения pointer'ов в smart-pointer. Это из пушки по воробьям.

Ты сильно не прав.
Вот представь. Копируешь ты объект с обычным указателем (даже не замечая, скажем, возвращая из функции по значению). И кто будет уничтожать твой пойнер? Правильно, тот кто первым разрушится. А второй объект будет обращаться к мусору. Вот радость-то.
С другой стороны, если ты используешь smart-pointer, компилятор просто не сможет сгенерировать копи-конструктор сам - обругается. Поэтому, если обяъект не должен копироваться - smart-pointer самое то. Только лучше бы явно сделать класс non_copyble. А если хочешь-таки копировать - не вопрос: либо пиши сам глубокий конструктор копирования, либо используй пойнтер с подсчетом ссылок.
ИМХО, издержки (написание кода или ознакомление с готовым классом) на использование разнообразных смарт-пойнтеров окупаются всегда.   

Автор: dizzy1984 17.4.2007, 21:40
Цитата(JackYF @  17.4.2007,  20:52 Найти цитируемый пост)
О чем и речь. Не раз указатели в полях моих классов ведут себя именно таким образом

Но ведь так не всегда. У меня нет нужды в операторе =, почему бы мне не использовать auto_ptr. Хотя для более общего случая можно поискать и более крутых смартпоинтеров.
Цитата(JackYF @  17.4.2007,  20:52 Найти цитируемый пост)
Прописать там одну строчку - не проблема, имхо.

Есть еще один момент во всей этой истории...
Динамически выделенная память не освобожается при срабатывании исключений.
Применимо для классов это значит, что есть вероятность ситуации, когда после выделения памяти под поля в конструкторе срабатывает исключение. деструкторы вызываются для уже созданных объектов, после чего происходит разворачивание стека. Разворачиваясь стек давит автоматические переменные. Если такая автоматическая переменная будет смартпоинтером, то она может в своем деструкторе освободить память под объект.
Вообщем-то для этого он и создавался.  smile 
Не против забывчивых людей, но для защиты от исключений в конструкторах и функциях.
В функции история такая же. Если в ней динамически выделяется объект, есть возможность порождения исключения, значит есть вероятность утечки память, т.к сработав, исключение обойдет участок кода, где человек с хорошей памятью smile поставил процедуру отчистки.
Цитата(JackYF @  17.4.2007,  20:52 Найти цитируемый пост)
 Это из пушки по воробьям.

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

Автор: JackYF 18.4.2007, 13:17
Цитата(Earnest @  17.4.2007,  21:32 Найти цитируемый пост)
Вот представь. Копируешь ты объект с обычным указателем (даже не замечая, скажем, возвращая из функции по значению). И кто будет уничтожать твой пойнер? Правильно, тот кто первым разрушится. А второй объект будет обращаться к мусору. Вот радость-то.


Согласен. Но эта проблема столько раз поднималась в книжках... поэтому
если класс все-таки copyable, то я, когда пишу конструкторы к нему, автоматом пишу и конструктор копий + operator=. Привычка уже выработалась, что ли. 

Цитата(Earnest @  17.4.2007,  21:32 Найти цитируемый пост)
Копируешь ты объект с обычным указателем

Опять-таки имхо, но обычные указатели в классах я храню крайне редко. Гораздо чаще я храню там обычные/не очень массивы (объектами, со всеми преимуществами наличия деструкторов и т.д.).
Обычные указатели у меня хранятся в самых базовых и/или абстрактных классах, которые все-таки пишутся сосредоточенно и отлаживаются тоже жестко. Стоит ли применять там smart-pointer'ы? Просто это или тот же класс массива, или другой тип умного указателя.
В общем, если не из пушки, то из базуки.

Цитата(dizzy1984 @  17.4.2007,  21:40 Найти цитируемый пост)
Но ведь так не всегда. У меня нет нужды в операторе =

у меня в 95% оператор= есть.

Цитата(dizzy1984 @  17.4.2007,  21:40 Найти цитируемый пост)
Динамически выделенная память не освобожается при срабатывании исключений.

Этот момент есть. Тут согласен.

Автор: Earnest 19.4.2007, 07:54
Цитата(JackYF @  18.4.2007,  14:17 Найти цитируемый пост)
если класс все-таки copyable, то я, когда пишу конструкторы к нему, автоматом пишу и конструктор копий + operator=. Привычка уже выработалась, что ли. 

Это хорошо, что выработалась. 
А если указатель добавляется в класс не сразу, а в процессе поддержки, и не тобой, а тем, у кого еще не выработалась?
А если класс не copyable? А ты ошибешься? Компилятор для класса с указателям сгенерирует коструктор копирования запросто. Конечно, можно заранее принимать для этого меры, т.е. сразу объявляетть класс как Non-copyable, и это правильно.
Но это меры того же порядка, как использование смарт-пойнтеров вместо указателей, что ты считаешь "пушкой по воробьям". А это вовсе не пушка, а просто чуть модифицированная рогатка: накладных расходов практически никаких (или вовсе никаких, если нет подсчета ссылок), все инлайн.  Тебя пугает код смарт-пойнтера? Так в шаблонах длина написанного кода никак не влияет на размер результирующего exe.

У одного из гуру программирования я встречала фразу: самый безопасный код - этот тот, которого нет. Отсюда следует вывод: все, что можно поручить компилятору, пусть он и делает. Т.е. самые лучшие деструкторы - это пустые (в твоем коде, разумеется). Захват ресурса == инициализация. И т.д.

Автор: JackYF 19.4.2007, 15:56
Цитата(Earnest @  19.4.2007,  07:54 Найти цитируемый пост)
У одного из гуру программирования я встречала фразу: самый безопасный код - этот тот, которого нет.


Хорошая фраза.

Цитата(Earnest @  19.4.2007,  07:54 Найти цитируемый пост)
ебя пугает код смарт-пойнтера?

Да нет, не очень smile и сам писал, чего уж тут пугаться...

Цитата(Earnest @  19.4.2007,  07:54 Найти цитируемый пост)
А если указатель добавляется в класс не сразу, а в процессе поддержки, и не тобой, а тем, у кого еще не выработалась?

Ну, тогда не фарт.


Согласен. Да. Доводов против не имею.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)