Здравствуйте, _Winnie, Вы писали:
_W>Обычно отвечают "сделай private конструктор и порождающую функцию". Но это pain и bore писать для каждого класса такую функцию. А написать обобщенную невозможно. Но всё гораздо проще. Не нужно обобщенной Create. Сделаем обобщённый Destroy. Всё равно нужно что-то писать, но уже гораздо меньше.
Идея — супер! Пора бы тебе для нее и название подобрать... Вот мой вариант:
(c) _Winnie Fast Antistack Idiom. (WFAI) :)
C++ можно выучить за 21 день! ...если дни — полярные.
ME>В то время, когда правильный ответ: "Это нафиг не никому надо, займись лучше делом."
Нет, Maxim Yegorushkin, мы не позволим тебе заставить _Winnie заняться делом.
Ибо в его творениях мировой юмор приобретает гораздо больше, чем теряет программирование.
On Wed, 19 Oct 2005 18:02:33 +0400, Alxndr <14348@users.rsdn.ru> wrote:
> Здравствуйте, MaximE, Вы писали: > >>> Не ты ли недавно рассказывал, что 80% (с цифрой могу соврать) твоих классов являются некопируемыми? > > ME>Это несколько из другой оперы. В С/С++ нет нотации не-value типа, поэтому приходится ее симулировать хэком с private конструктором копий и оператора присваивания. > > Извини, не понял: что мешает сделать простой комментарий >
> // Эта структура не должна копироваться!
> struct MyStruct
> {
> ...
> };
>
> Если сильно приспичило — копируй, caveat emptor — в комментарии.
Мешает то, что C++ сгенерирует за меня вышеупомянутые члены (почему бы ему еще не сгенерить канонические ф-ции-члены foo и bar?). Если бы эти члены не генерились компилятором, т.е. если бы С++ по-умолчанию не предполагал, что это value-тип, тот хэк не понадобился бы.
Вобщем-то, здесь можно обойтись без private, достаточно объявить члены, но не определить из. Тогда ошибка отложится на этап линковки и диагностика будет менее подробной, что не удобно и не приемлимо для библиотек, которые могут иметь неразрешенные ссылки.
Здравствуйте, Alxndr, Вы писали:
A>Здравствуйте, MaximE, Вы писали:
>>> Обычно отвечают "сделай private конструктор и порождающую функцию".
ME>>В то время, когда правильный ответ: "Это нафиг не никому надо, займись лучше делом."
A>Максим, а ты действительно считаешь, что это нафиг никому не надо?
Действительно.
A>Ведь такие вещи как минимум способствуют лучшему пониманию языка
Не отрицаю возможной образовательной ценности, но отрицаю практическую ценность запретов вообще.
К примеру, в Python нет спецификаторов доступа, и ничего — все довольны. А посмотрите в код boost::multi_index, сколько усилий было затрачено на расстановку спецификаторов доступа, сколько макросов совместимости навернуто. А ради чего? Я не могу вспомнить за свою практику случая, когда бы я пытался вызвать непубличную ф-цию boost::multi_index, std::map или какого другого класса.
Зачем запрещать создавать объекты где угодно, зачем запрещать наследовать от своих классов? От всех наивных программистов все равно не защититься.
Здравствуйте, __LP, Вы писали:
__L>Здравствуйте, _Winnie, Вы писали:
__L>Идея — супер! Пора бы тебе для нее и название подобрать... Вот мой вариант: __L>(c) _Winnie Fast Antistack Idiom. (WFAI)
Мои 5копеек:
А все Идиомы от известного кутюрье собрать в одно месте и как нить назвать, неброско, но со вкусом:
All _Winnie Idiom (AWI)
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[2]: Зачем запрещать создавать объект на стеке? :)
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, _Winnie, Вы писали:
E>А таки открой тайну, зачем это надо? E>Тут развёлся флейм по поводу того, что тип анадо не надо, но никто примера когда надо так и не привёл. E>Может ты откроешь, зачем тебе это понадобилось?
Просто иногда на rsdn спрашивают... мне это нафиг не нужно, я MaximE поставил плюсик в сообщении "тебе это не нужно"
Правильно работающая программа — просто частный случай Undefined Behavior
Обычно отвечают "сделай private конструктор и порождающую функцию". Но это pain и bore писать для каждого класса такую функцию. А написать обобщенную невозможно. Но всё гораздо проще. Не нужно обобщенной Create. Сделаем обобщённый Destroy. Всё равно нужно что-то писать, но уже гораздо меньше.
class X
{
private:
virtual ~X() {}
friend void kill<X>(X *x);
};
int main()
{
{
X *p = new X;
kill(p); //OK.
}
{
X x;
//error: `virtual X::~X()' is private
}
}
Правильно работающая программа — просто частный случай Undefined Behavior
Re[5]: Зачем запрещать создавать объект на стеке? :)
Здравствуйте, srggal, Вы писали:
S>Я сторонник запрета создания объекта в куче ( в некоторых случаях ), но к сожалению решения этой задачи пока не видел.
class test
{
static void* operator new(size_t n);
};
test t1;//okint main()
{
test t2;//ok
test* t3 = new test();//errorreturn 0;
}
Любите книгу — источник знаний (с) М.Горький
Re[7]: Зачем запрещать создавать объект на стеке? :)
Едея не нова . У Майерса в "More effective C++", правило 27, описывается подобный подход с закрытым деструктором, только он предлагает для уничтожения использовать функцию-член, что, ИМХО, более правильно, т.к. не требует никаких внешних функций.
class test
{
~test() {}
public:
void destroy() { delete this; }
};
test t;//errorint main()
{
test t1;//error
test* t2 = new test();//okdelete t2;//error
t2->destroy();//okreturn 0;
}
Здравствуйте, _Winnie, Вы писали:
_W>Обычно отвечают "сделай private конструктор и порождающую функцию". Но это pain и bore писать для каждого класса такую функцию. А написать обобщенную невозможно. Но всё гораздо проще. Не нужно обобщенной Create. Сделаем обобщённый Destroy. Всё равно нужно что-то писать, но уже гораздо меньше.
Приватным конструктор делать не надо, иначе не сможешь делать new, а это в наши планы не входит.
На самом деле, достаточно сделать закрытым деструктор.
Здравствуйте, _Winnie, Вы писали:
_W>Обычно отвечают "сделай private конструктор и порождающую функцию". Но это pain и bore писать для каждого класса такую функцию. А написать обобщенную невозможно. Но всё гораздо проще. Не нужно обобщенной Create. Сделаем обобщённый Destroy. Всё равно нужно что-то писать, но уже гораздо меньше.
А может лучше assert в конструкторе на то, что this не слишком отличается от адреса какой-то переменной на стеке?
Но конечно "ещё более правильный" совет дал Maxim Yegorushkin здесь
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, MaximE, Вы писали:
>> Обычно отвечают "сделай private конструктор и порождающую функцию".
ME>В то время, когда правильный ответ: "Это нафиг не никому надо, займись лучше делом."
Максим, а ты действительно считаешь, что это нафиг никому не надо?
Ведь такие вещи как минимум способствуют лучшему пониманию языка
Здравствуйте, MaximE, Вы писали:
A>>Ведь такие вещи как минимум способствуют лучшему пониманию языка
ME>Не отрицаю возможной образовательной ценности, но отрицаю практическую ценность запретов вообще.
Пардон, а, например, статическая типизация в C++ — это ведь тоже своего рода система запретов?
ME>К примеру, в Python нет спецификаторов доступа, и ничего — все довольны. А посмотрите в код boost::multi_index, сколько усилий было затрачено на расстановку спецификаторов доступа, сколько макросов совместимости навернуто. А ради чего?
Может, ради "защиты от дурака"?
ME>Я не могу вспомнить за свою практику случая, когда бы я пытался вызвать непубличную ф-цию boost::multi_index, std::map или какого другого класса.
Поэтому ты считаешь, что это для всех бесполезно?
ME>Зачем запрещать создавать объекты где угодно, зачем запрещать наследовать от своих классов? От всех наивных программистов все равно не защититься.
Не ты ли недавно рассказывал, что 80% (с цифрой могу соврать) твоих классов являются некопируемыми?
Здравствуйте, MaximE, Вы писали:
ME>А ради чего? Я не могу вспомнить за свою практику случая, когда бы я пытался вызвать непубличную ф-цию boost::multi_index, std::map или какого другого класса.
А как Вы, уважаемый Максим, узнаёте, какую функцию Вам не стоит вызывать ?
Предвосхищу ответ:
1) Из документации;
2) Если правильная архитектура, то "приватные" функции не прийдет в голову вызывать.
Касательно 1) — приходим у выводу что спецификаторы доступа делает код в каком-то смысле самодокументируемым
Касательно 2) — есть контр пример NVI
On Wed, 19 Oct 2005 17:27:54 +0400, Alxndr <14348@users.rsdn.ru> wrote:
> Здравствуйте, MaximE, Вы писали: > > A>>Ведь такие вещи как минимум способствуют лучшему пониманию языка > > ME>Не отрицаю возможной образовательной ценности, но отрицаю практическую ценность запретов вообще. > > Пардон, а, например, статическая типизация в C++ — это ведь тоже своего рода система запретов?
Это полезная вещь, не раз помогала.
[]
> ME>Я не могу вспомнить за свою практику случая, когда бы я пытался вызвать непубличную ф-цию boost::multi_index, std::map или какого другого класса. > > Поэтому ты считаешь, что это для всех бесполезно?
Потому что не знаю людей, кого бы это спасло от бага на этапе компиляции.
> ME>Зачем запрещать создавать объекты где угодно, зачем запрещать наследовать от своих классов? От всех наивных программистов все равно не защититься. > > Не ты ли недавно рассказывал, что 80% (с цифрой могу соврать) твоих классов являются некопируемыми?
Это несколько из другой оперы. В С/С++ нет нотации не-value типа, поэтому приходится ее симулировать хэком с private конструктором копий и оператора присваивания.
On Wed, 19 Oct 2005 17:36:04 +0400, srggal <21794@users.rsdn.ru> wrote:
> Здравствуйте, MaximE, Вы писали: > > ME>А ради чего? Я не могу вспомнить за свою практику случая, когда бы я пытался вызвать непубличную ф-цию boost::multi_index, std::map или какого другого класса. > > А как Вы, уважаемый Максим, узнаёте, какую функцию Вам не стоит вызывать ?
Из кода или комментария.
В том же Python ф-ции, которые не стоит вызывать из пользовательского кода оканчиваются на _. Но если очень хочется вызвать — никто запрещать не будет, caveat emptor.
Здравствуйте, Alxndr, Вы писали:
S>>Касательно 2) — есть контр пример NVI
A>Не вполне понятно, почему NVI — контрпример A>Там private функция замещается, а не вызывается.
ТОнкость этого Архитектурного решения состоит на мой взгляд в том,
что в руках потомках не оказывается способов воспользоваться замещенной функцией, ее использование возможно исключительно в Базовом классе. И именно это отличает NVI от шаблонного метода ( если не ошибаюсь )
Здравствуйте, MaximE, Вы писали:
ME>Из кода или комментария.
ME>В том же Python ф-ции, которые не стоит вызывать из пользовательского кода оканчиваются на _. Но если очень хочется вызвать — никто запрещать не будет, caveat emptor.
Ок, с питоном понятно, вопросов нет, но его Вы привели в качестве примера что эизнь на марсе есть, а как же с С++, что Вы скажете на это:
А как Вы, уважаемый Максим, узнаёте, какую функцию Вам не стоит вызывать ?
Предвосхищу ответ:
1) Из документации;
2) Если правильная архитектура, то "приватные" функции не прийдет в голову вызывать.
Касательно 1) — приходим у выводу что спецификаторы доступа делает код в каком-то смысле самодокументируемым
Касательно 2) — есть контр пример NVI
Здравствуйте, MaximE, Вы писали:
>> Не ты ли недавно рассказывал, что 80% (с цифрой могу соврать) твоих классов являются некопируемыми?
ME>Это несколько из другой оперы. В С/С++ нет нотации не-value типа, поэтому приходится ее симулировать хэком с private конструктором копий и оператора присваивания.
Извини, не понял: что мешает сделать простой комментарий
// Эта структура не должна копироваться!struct MyStruct
{
...
};
Если сильно приспичило — копируй, caveat emptor — в комментарии.
P.S. Я ни в коем случае не хочу тебе "поймать" или еще что-то там — я хочу разобраться и понимать этот язык лучше
Здравствуйте, Alxndr, Вы писали:
A>Здравствуйте, MaximE, Вы писали:
>>> Не ты ли недавно рассказывал, что 80% (с цифрой могу соврать) твоих классов являются некопируемыми?
ME>>Это несколько из другой оперы. В С/С++ нет нотации не-value типа, поэтому приходится ее симулировать хэком с private конструктором копий и оператора присваивания.
A>Извини, не понял: что мешает сделать простой комментарий A>
A>// Эта структура не должна копироваться!
A>struct MyStruct
A>{
A> ...
A>};
A>
A>Если сильно приспичило — копируй, caveat emptor — в комментарии.
A>P.S. Я ни в коем случае не хочу тебе "поймать" или еще что-то там — я хочу разобраться и понимать этот язык лучше
Смотри:
class SomeNonCopyAbleClass;
void Foo( SomeNonCopyAbleClass /*тут должна быть передача параметра по ссылке, но меня эта клавиша сломалась*/qwerty );
Далее, что происходит: в SomeNonCopyAbleClass есть некоторый хендел.... Продолжать надо или уже понятно?
Здравствуйте, MaximE, Вы писали:
ME>Здравствуйте, srggal, Вы писали:
S>>
S>>А как Вы, уважаемый Максим, узнаёте, какую функцию Вам не стоит вызывать ?
S>>Предвосхищу ответ:
S>>1) Из документации;
S>>2) Если правильная архитектура, то "приватные" функции не прийдет в голову вызывать.
S>>Касательно 1) — приходим у выводу что спецификаторы доступа делает код в каком-то смысле самодокументируемым
S>>Касательно 2) — есть контр пример NVI
S>>ЗЫ Интересует Ваше мнение по этому вопросу.
ME>
Здравствуйте, LuciferMoscow, Вы писали:
LM>Смотри: LM>
LM>class SomeNonCopyAbleClass;
LM>void Foo( SomeNonCopyAbleClass /*тут должна быть передача параметра по ссылке, но меня эта клавиша сломалась*/qwerty );
LM>
LM>Далее, что происходит: в SomeNonCopyAbleClass есть некоторый хендел.... Продолжать надо или уже понятно?
Я понимаю, зачем делать класс некопируемым. Я НЕ понимаю, почему это пример из другой оперы: там мы делаем закрытой одну функцию-член, здесь — другую.
Здравствуйте, Alxndr, Вы писали:
A>Здравствуйте, LuciferMoscow, Вы писали:
LM>>Смотри: LM>>
LM>>class SomeNonCopyAbleClass;
LM>>void Foo( SomeNonCopyAbleClass /*тут должна быть передача параметра по ссылке, но меня эта клавиша сломалась*/qwerty );
LM>>
LM>>Далее, что происходит: в SomeNonCopyAbleClass есть некоторый хендел.... Продолжать надо или уже понятно?
A>Я понимаю, зачем делать класс некопируемым. Я НЕ понимаю, почему это пример из другой оперы: там мы делаем закрытой одну функцию-член, здесь — другую.
Потому, что я огреб БОЛЬШИЕ проблемы из-за ОДНОГО символа. Мне показалось, что это хороший пример.
Здравствуйте, _Winnie, Вы писали:
_W>Обычно отвечают "сделай private конструктор и порождающую функцию". Но это pain и bore писать для каждого класса такую функцию. А написать обобщенную невозможно. Но всё гораздо проще. Не нужно обобщенной Create. Сделаем обобщённый Destroy. Всё равно нужно что-то писать, но уже гораздо меньше.
А таки открой тайну, зачем это надо?
Тут развёлся флейм по поводу того, что тип анадо не надо, но никто примера когда надо так и не привёл.
Может ты откроешь, зачем тебе это понадобилось?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Зачем запрещать создавать объект на стеке? :)
Здравствуйте, Erop, Вы писали:
E>А таки открой тайну, зачем это надо? E>Тут развёлся флейм по поводу того, что тип анадо не надо, но никто примера когда надо так и не привёл. E>Может ты откроешь, зачем тебе это понадобилось?
OS Симбиан, в которой рекомендкется очень обдуманно использовать стэк.
Здравствуйте, Alxndr, Вы писали:
A>Ясно. Просто не к месту был употреблен термин "контрпример"
Дело в том, Коллега, что термин этот был употреблен ИМХО правильно.
Поскольку
...
2) Если правильная архитектура, то "приватные" функции не прийдет в голову вызывать.
...
Касательно 2) — есть контр пример NVI
Поскольку, вариант ответа 2 — подразумевает Архитектуру и речь бы шла о том, что при правильной Архитектуре вопросы приватности не должны возникать,
то я сразу привео контр пример — NVI — Архитектурное решение, которое основано на использовании приватности. Что и показывает, естественно в общем случае, необоснованность 2го варианта ответа.
Но коварный Максим скрылся за
caveat emptor
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[2]: Как запретить создавать объект на стеке?
От:
Аноним
Дата:
19.10.05 18:20
Оценка:
ME>В то время, когда правильный ответ: "Это нафиг не никому надо, займись лучше делом."
Тут ты не прав. примеры:
COM объект должен запрещать создавать себя на стеке, Так же класс виндовского окошка должен запрещать это делать.
В принципе любой класс который занимается самоуничтожением.
Здравствуйте, Аноним, Вы писали:
ME>>В то время, когда правильный ответ: "Это нафиг не никому надо, займись лучше делом."
А>Тут ты не прав. примеры:
А>COM объект должен запрещать создавать себя на стеке,
COM объект создается фабрикой. Ты — автор кокласса и фабрики (уже забыл, но в ATL вроде и фабрику самому писать не нужно). Ты настолько рассеян, что твоя фабрика может по ошибке создать объект на стэке?
А>Так же класс виндовского окошка должен запрещать это делать.
Контр-пример — оконные классы MFC.
А>В принципе любой класс который занимается самоуничтожением.
Не помню, сталкивался ли с таким дизайном. Классы, доступные пользователю, так себя не могут вести — ты создал объект по new, имеешь на него указатель, а он возьми и удали себя, оставив тебя с dangling pointer?
Здравствуйте, srggal, Вы писали:
S>Здравствуйте, __LP, Вы писали:
__L>>Здравствуйте, _Winnie, Вы писали:
__L>>Идея — супер! Пора бы тебе для нее и название подобрать... Вот мой вариант: __L>>(c) _Winnie Fast Antistack Idiom. (WFAI)
S>Мои 5копеек: S> А все Идиомы от известного кутюрье собрать в одно месте и как нить назвать, неброско, но со вкусом: S> All _Winnie Idiom (AWI)
Здравствуйте, MaximE, Вы писали:
А>>Так же класс виндовского окошка должен запрещать это делать. ME>Контр-пример — оконные классы MFC.
А>>В принципе любой класс который занимается самоуничтожением. ME>Не помню, сталкивался ли с таким дизайном. Классы, доступные пользователю, так себя не могут вести — ты создал объект по new, имеешь на него указатель, а он возьми и удали себя, оставив тебя с dangling pointer?
Ну в том же MFC бывают оконные классы, экземплярами которых никто не владеет, и они разрушают себя себя сами по OnPostNcDestroy().
Например, такими являются главные окна MDI MFC приложений.
Но в целом я согласен
Окна часто оказываются чьими-то полями или ещё как-то с кем-то связанными.
Ну и вообще те объекты, которые сами себе говорят delete this, обычно и так всё хорошо запрещают. Так как первая же попытка разрушения таких объектов вызовет assert в куче, да и всё.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Зачем запрещать создавать объект на стеке? :)
Здравствуйте, srggal, Вы писали:
S>Здравствуйте, Erop, Вы писали:
E>>А таки открой тайну, зачем это надо? E>>Тут развёлся флейм по поводу того, что тип анадо не надо, но никто примера когда надо так и не привёл. E>>Может ты откроешь, зачем тебе это понадобилось?
S>OS Симбиан, в которой рекомендкется очень обдуманно использовать стэк.
S>Это так, навскидку
Спасибо, конечно за пример, но не совсем понятно зачем под OS Симбиан запрещать это для каких-то объектов?
Казалось бы весь стиль программирования будет направлен на то, чтобы избежать объектов на стеке
Тем более, что описанный трюк ещё запрещает объектам быть и полями
Может стоит вообще организовать исскуственный "стек", в котором лежат структуры, соответсвующие автоматическим переменным, и на входе в функцию такой "фрейм" в стек класть, а на выходе разрушать?
ТОгда тем более описанный трюк будет вреден
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
А если требуется разрешить наследование от подобных классов (например, для "самоудаляющихся" оконных объектов)? Ведь тогда деструктор или конструкторы нельзя делать заркытыми, только защищёнными. А это значит, что потомок может их вытащить наружу...
Здравствуйте, Erop, Вы писали:
E>Спасибо, конечно за пример, но не совсем понятно зачем под OS Симбиан запрещать это для каких-то объектов? E>Казалось бы весь стиль программирования будет направлен на то, чтобы избежать объектов на стеке E>Тем более, что описанный трюк ещё запрещает объектам быть и полями
E>Может стоит вообще организовать исскуственный "стек", в котором лежат структуры, соответсвующие автоматическим переменным, и на входе в функцию такой "фрейм" в стек класть, а на выходе разрушать?
E>ТОгда тем более описанный трюк будет вреден
Самомму не понятно
Но Вы хотели пример, я привел первый мало-мальски подходящий пример.
Это не значит что я сам являюсь сторонником запретов создания на стэке.
Я сторонник запрета создания объекта в куче ( в некоторых случаях ), но к сожалению решения этой задачи пока не видел.
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[6]: Зачем запрещать создавать объект на стеке? :)
Здравствуйте, Bell, Вы писали:
B> В общем случае — никак, как говорил товарищ Майерс.
Не факт. Препроцессорная магия: Куча ifdef / elif как бусте для каждой платформы и error для новой