Как запретить создавать объект на стеке?
От: _Winnie Россия C++.freerun
Дата: 19.10.05 10:56
Оценка: :)
Обычно отвечают "сделай private конструктор и порождающую функцию". Но это pain и bore писать для каждого класса такую функцию. А написать обобщенную невозможно. Но всё гораздо проще. Не нужно обобщенной Create. Сделаем обобщённый Destroy. Всё равно нужно что-то писать, но уже гораздо меньше.

Ответ:

//maybe, boost::checked_delete ?
template <class T>
void kill(T *p) 
{
    (void)sizeof(T);
    delete p;
}




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: Как запретить создавать объект на стеке?
От: Bell Россия  
Дата: 19.10.05 11:15
Оценка:
Здравствуйте, _Winnie, Вы писали:

Едея не нова . У Майерса в "More effective C++", правило 27, описывается подобный подход с закрытым деструктором, только он предлагает для уничтожения использовать функцию-член, что, ИМХО, более правильно, т.к. не требует никаких внешних функций.


class test
{
   ~test() {}
public:
   void destroy() { delete this; }
};

test t;//error

int main()
{
   test t1;//error
   test* t2 = new test();//ok
   delete t2;//error
   t2->destroy();//ok
   return 0;
}
Любите книгу — источник знаний (с) М.Горький
Re: Как запретить создавать объект на стеке?
От: jazzer Россия Skype: enerjazzer
Дата: 19.10.05 11:25
Оценка:
Здравствуйте, _Winnie, Вы писали:

_W>Обычно отвечают "сделай private конструктор и порождающую функцию". Но это pain и bore писать для каждого класса такую функцию. А написать обобщенную невозможно. Но всё гораздо проще. Не нужно обобщенной Create. Сделаем обобщённый Destroy. Всё равно нужно что-то писать, но уже гораздо меньше.


Приватным конструктор делать не надо, иначе не сможешь делать new, а это в наши планы не входит.
На самом деле, достаточно сделать закрытым деструктор.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Как запретить создавать объект на стеке?
От: MaximE Великобритания  
Дата: 19.10.05 11:30
Оценка: 34 (6) +4 :))) :))) :))) :))) :))) :)))
On Wed, 19 Oct 2005 14:56:17 +0400, _Winnie <23256@users.rsdn.ru> wrote:

> Обычно отвечают "сделай private конструктор и порождающую функцию".


В то время, когда правильный ответ: "Это нафиг не никому надо, займись лучше делом."

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re: Как запретить создавать объект на стеке?
От: Erop Россия  
Дата: 19.10.05 11:41
Оценка:
Здравствуйте, _Winnie, Вы писали:

_W>Обычно отвечают "сделай private конструктор и порождающую функцию". Но это pain и bore писать для каждого класса такую функцию. А написать обобщенную невозможно. Но всё гораздо проще. Не нужно обобщенной Create. Сделаем обобщённый Destroy. Всё равно нужно что-то писать, но уже гораздо меньше.


А может лучше assert в конструкторе на то, что this не слишком отличается от адреса какой-то переменной на стеке?

Но конечно "ещё более правильный" совет дал Maxim Yegorushkin здесь
Автор: MaximE
Дата: 19.10.05
+1
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: Как запретить создавать объект на стеке?
От: sch  
Дата: 19.10.05 12:46
Оценка: :))) :)
ME>В то время, когда правильный ответ: "Это нафиг не никому надо, займись лучше делом."

Нет, Maxim Yegorushkin, мы не позволим тебе заставить _Winnie заняться делом.
Ибо в его творениях мировой юмор приобретает гораздо больше, чем теряет программирование.
Re[2]: Как запретить создавать объект на стеке?
От: Alxndr Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 19.10.05 12:49
Оценка:
Здравствуйте, MaximE, Вы писали:

>> Обычно отвечают "сделай private конструктор и порождающую функцию".


ME>В то время, когда правильный ответ: "Это нафиг не никому надо, займись лучше делом."


Максим, а ты действительно считаешь, что это нафиг никому не надо?
Ведь такие вещи как минимум способствуют лучшему пониманию языка
Re: Как запретить создавать объект на стеке?
От: __LP  
Дата: 19.10.05 12:57
Оценка: :))) :))
Здравствуйте, _Winnie, Вы писали:

_W>Обычно отвечают "сделай private конструктор и порождающую функцию". Но это pain и bore писать для каждого класса такую функцию. А написать обобщенную невозможно. Но всё гораздо проще. Не нужно обобщенной Create. Сделаем обобщённый Destroy. Всё равно нужно что-то писать, но уже гораздо меньше.


Идея — супер! Пора бы тебе для нее и название подобрать... Вот мой вариант:
(c) _Winnie Fast Antistack Idiom. (WFAI) :)
C++ можно выучить за 21 день! ...если дни — полярные.
Re[3]: Как запретить создавать объект на стеке?
От: MaximE Великобритания  
Дата: 19.10.05 13:15
Оценка: -2
Здравствуйте, Alxndr, Вы писали:

A>Здравствуйте, MaximE, Вы писали:


>>> Обычно отвечают "сделай private конструктор и порождающую функцию".


ME>>В то время, когда правильный ответ: "Это нафиг не никому надо, займись лучше делом."


A>Максим, а ты действительно считаешь, что это нафиг никому не надо?


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

A>Ведь такие вещи как минимум способствуют лучшему пониманию языка


Не отрицаю возможной образовательной ценности, но отрицаю практическую ценность запретов вообще.

К примеру, в Python нет спецификаторов доступа, и ничего — все довольны. А посмотрите в код boost::multi_index, сколько усилий было затрачено на расстановку спецификаторов доступа, сколько макросов совместимости навернуто. А ради чего? Я не могу вспомнить за свою практику случая, когда бы я пытался вызвать непубличную ф-цию boost::multi_index, std::map или какого другого класса.

Зачем запрещать создавать объекты где угодно, зачем запрещать наследовать от своих классов? От всех наивных программистов все равно не защититься.
Re[4]: Как запретить создавать объект на стеке?
От: Alxndr Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 19.10.05 13:27
Оценка:
Здравствуйте, MaximE, Вы писали:

A>>Ведь такие вещи как минимум способствуют лучшему пониманию языка


ME>Не отрицаю возможной образовательной ценности, но отрицаю практическую ценность запретов вообще.


Пардон, а, например, статическая типизация в C++ — это ведь тоже своего рода система запретов?

ME>К примеру, в Python нет спецификаторов доступа, и ничего — все довольны. А посмотрите в код boost::multi_index, сколько усилий было затрачено на расстановку спецификаторов доступа, сколько макросов совместимости навернуто. А ради чего?


Может, ради "защиты от дурака"?

ME>Я не могу вспомнить за свою практику случая, когда бы я пытался вызвать непубличную ф-цию boost::multi_index, std::map или какого другого класса.


Поэтому ты считаешь, что это для всех бесполезно?

ME>Зачем запрещать создавать объекты где угодно, зачем запрещать наследовать от своих классов? От всех наивных программистов все равно не защититься.


Не ты ли недавно рассказывал, что 80% (с цифрой могу соврать) твоих классов являются некопируемыми?
Re[4]: Как запретить создавать объект на стеке?
От: srggal Украина  
Дата: 19.10.05 13:36
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>А ради чего? Я не могу вспомнить за свою практику случая, когда бы я пытался вызвать непубличную ф-цию boost::multi_index, std::map или какого другого класса.


А как Вы, уважаемый Максим, узнаёте, какую функцию Вам не стоит вызывать ?

Предвосхищу ответ:
1) Из документации;
2) Если правильная архитектура, то "приватные" функции не прийдет в голову вызывать.

Касательно 1) — приходим у выводу что спецификаторы доступа делает код в каком-то смысле самодокументируемым
Касательно 2) — есть контр пример NVI
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[5]: Как запретить создавать объект на стеке?
От: Alxndr Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 19.10.05 13:38
Оценка:
Здравствуйте, srggal, Вы писали:

S>2) Если правильная архитектура, то "приватные" функции не прийдет в голову вызывать.


<...>

S>Касательно 2) — есть контр пример NVI


Не вполне понятно, почему NVI — контрпример
Там private функция замещается, а не вызывается.
Re[5]: Как запретить создавать объект на стеке?
От: MaximE Великобритания  
Дата: 19.10.05 13:41
Оценка:
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 конструктором копий и оператора присваивания.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 2.0 beta
Re[5]: Как запретить создавать объект на стеке?
От: MaximE Великобритания  
Дата: 19.10.05 13:46
Оценка:
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.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 2.0 beta
Re[6]: Как запретить создавать объект на стеке?
От: srggal Украина  
Дата: 19.10.05 13:47
Оценка:
Здравствуйте, Alxndr, Вы писали:

S>>Касательно 2) — есть контр пример NVI


A>Не вполне понятно, почему NVI — контрпример

A>Там private функция замещается, а не вызывается.

ТОнкость этого Архитектурного решения состоит на мой взгляд в том,
что в руках потомках не оказывается способов воспользоваться замещенной функцией, ее использование возможно исключительно в Базовом классе. И именно это отличает NVI от шаблонного метода ( если не ошибаюсь )
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[6]: Как запретить создавать объект на стеке?
От: srggal Украина  
Дата: 19.10.05 13:50
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Из кода или комментария.


ME>В том же Python ф-ции, которые не стоит вызывать из пользовательского кода оканчиваются на _. Но если очень хочется вызвать — никто запрещать не будет, caveat emptor.


Ок, с питоном понятно, вопросов нет, но его Вы привели в качестве примера что эизнь на марсе есть, а как же с С++, что Вы скажете на это:

А как Вы, уважаемый Максим, узнаёте, какую функцию Вам не стоит вызывать ?

Предвосхищу ответ:
1) Из документации;
2) Если правильная архитектура, то "приватные" функции не прийдет в голову вызывать.

Касательно 1) — приходим у выводу что спецификаторы доступа делает код в каком-то смысле самодокументируемым
Касательно 2) — есть контр пример NVI


ЗЫ Интересует Ваше мнение по этому вопросу.
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[7]: Как запретить создавать объект на стеке?
От: Alxndr Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 19.10.05 13:52
Оценка:
Здравствуйте, srggal, Вы писали:

S>ТОнкость этого Архитектурного решения состоит на мой взгляд в том...


Ясно. Просто не к месту был употреблен термин "контрпример"
Re[7]: Как запретить создавать объект на стеке?
От: MaximE Великобритания  
Дата: 19.10.05 13:55
Оценка: +1 :)
Здравствуйте, srggal, Вы писали:

S>

S>А как Вы, уважаемый Максим, узнаёте, какую функцию Вам не стоит вызывать ?

S>Предвосхищу ответ:
S>1) Из документации;
S>2) Если правильная архитектура, то "приватные" функции не прийдет в голову вызывать.

S>Касательно 1) — приходим у выводу что спецификаторы доступа делает код в каком-то смысле самодокументируемым
S>Касательно 2) — есть контр пример NVI


S>ЗЫ Интересует Ваше мнение по этому вопросу.


Из кода или комментария.

Re[6]: Как запретить создавать объект на стеке?
От: Alxndr Германия http://www.google.com/profiles/alexander.poluektov#buzz
Дата: 19.10.05 14:02
Оценка:
Здравствуйте, MaximE, Вы писали:

>> Не ты ли недавно рассказывал, что 80% (с цифрой могу соврать) твоих классов являются некопируемыми?


ME>Это несколько из другой оперы. В С/С++ нет нотации не-value типа, поэтому приходится ее симулировать хэком с private конструктором копий и оператора присваивания.


Извини, не понял: что мешает сделать простой комментарий
// Эта структура не должна копироваться!
struct MyStruct
{
    ...
};

Если сильно приспичило — копируй, caveat emptor — в комментарии.

P.S. Я ни в коем случае не хочу тебе "поймать" или еще что-то там — я хочу разобраться и понимать этот язык лучше
Re[7]: Как запретить создавать объект на стеке?
От: LuciferMoscow Россия  
Дата: 19.10.05 14:09
Оценка:
Здравствуйте, 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 есть некоторый хендел.... Продолжать надо или уже понятно?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.