- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
template <typename T>class CleverPtr
{
T* ptr;
public:
~CleverPtr () { delete ptr; }
CleverPtr () : ptr(new T) {}
CleverPtr(const CleverPtr& other)
:ptr(new T) // <--- если напрягает, используйте делегирующий конструктор с++11
{
operator =(other);
}
CleverPtr& operator = (const CleverPtr& other)
{
if (this != &other)
*ptr = *other.ptr;
return *this;
}
};
LispGovno 20.02.2014 13:35 # +4
Soul_re@ver 20.02.2014 14:15 # 0
defecate-plusplus 20.02.2014 14:28 # +1
Soul_re@ver 20.02.2014 15:02 # 0
Смысла в этом не очень вижу, разве что как обёртку над PIMPL указателями, чтобы не писать свои деструктор и оператор присваивания.
Куда интереснее была бы идея COW указателя.
bormand 20.02.2014 19:24 # +1
А как он узнает, что в объект кто-то писал? А по любой неконстантной разадресации делать detach() - не комильфо.
laMer007 21.02.2014 02:47 # +1
Хотя идея далеко не благая, но в ад всё равно ведёт.
bormand 21.02.2014 06:45 # 0
roman-kashitsyn 20.02.2014 14:46 # +1
TarasB 20.02.2014 14:51 # +1
bormand 20.02.2014 19:09 # 0
Ну нахуя? Там и так по умолчанию генерится адекватный оператор присваивания и копирующий конструктор...
Писать деструкторы, операторы присваивания и копикторы/мувикторы приходится только в низкоуровневых классах. В остальных случаях почти всегда хватает дефолтовых.
TarasB 20.02.2014 19:13 # 0
про классы, в которых не надо писать свою логику в деструкторе, и так ясно, не про них речь
bormand 20.02.2014 19:34 # 0
TarasB 20.02.2014 20:03 # 0
Правда на 90% в них вообще T(T) не нужен, но опять же - а чего это я должен руками банить обоих, и T(T) и =(T)?
bormand 21.02.2014 06:43 # 0
Скажите, а boost::noncopyable не может спасти гиганта мысли?
TarasB 21.02.2014 09:46 # 0
bormand 21.02.2014 09:58 # 0
bormand 21.02.2014 07:38 # 0
Ну это само собой: откаты транзакций (RAIIшная обертка над транзакцией), тот же std::lock_guard (RAIIшная обертка над lock/unlock).
Но это же все низкоуровневые классы, которые пишутся один раз...
> пометить объект - снять пометку с объекта
Можно пример из практики?
TarasB 21.02.2014 09:53 # +1
Долго рассказывать, но попробую.
Задача такая, есть дохрена большой, допустим, граф, дохренища большой, размером N. И надо, допустим, сделать обход в ширину из вершины А, чтобы найти путь в вершину, обладающую свойством Б. И вы знаем, что обойдём мы при этом лишь небольшую часть графа, размером M.
Короче, надо как-то помечать обойдённые вершины. И уложиться в O(M). Как?
Проблема в том, как быстро убирать пометки с обойдённых вершин.
1, брутальное. Просто заводить булевый массив размера N и мемсетом занулять. Алгоритмическая сложность уже не та, но мемсет отработает сравнительно быстро.
2, хеш, хранящий обойдённый вершины, быстро обнуляется, быстро ищется. Переубийство, я считаю.
3, каждая вершина хранит момент времени (номер тика), когда её в последний раз обходили, то есть вместо if passed[i] надо писать if passed[i]==currentTick. Проблема в том, что тик может переполниться за край и тогда неверно отработается "вершина помечена", хотя на самом деле мы её помечали 2**32 тиков назад. Решения:
2а). инт64, тогда надо долго ждать перед переполнением. Но это как-то антиинженерно, как сказали в треде, где сия проблема обсуждалась.
2б). вот тут ваще пиздец и в это надо врубаться специально, но короче против вершин, хранящих очень старое значение, есть такой приём: после каждой пометки вершины как обойдённной, надо одну из других вершин пометить числом currentTick-1, так, чтобы через N тиков все вершины содержали число, не меньшее, чем currentTick-N-1
3) моё решение брутально и тупое, но я пока не скажу
bormand 21.02.2014 10:15 # 0
В postgres есть аналогичная проблема с номерами транзакций. Если ты выключишь autovacuum, который помимо сжатия таблиц меняет айдишки слишком старых транзакций на специальное число (то ли 0 то ли -1), которое заведомо меньше любых реальных xid'ов, то через 2^31 транзакций кровь-кишки-полбазы-пропало.
> Переубийство, я считаю.
Если у тебя несколько потоков и более-менее статичный граф - то других вариантов походу и нет. Ибо если ставить метки в самом графе - придется блочить его, что убьет весь профит от потоков.
> моё решение брутально и тупое, но я пока не скажу
Набиваешь в какой-нибудь контейнер, умеющий вставку за O(1) объекты, которые в деструкторе снимают метки с соотв. узлов графа?
TarasB 21.02.2014 10:17 # 0
Ёпт, ты догадливый.
Контейнер этот - тарасомассив. Размер графа известен, так что сколько памяти выделить - тоже известно.
Осталось только таскать ссылку на этот массив во всех методах.
defecate-plusplus 20.02.2014 19:20 # +2
а Тарас тебе что, сраный быдлокодер-формошлёп?
велосипед - вообще самый экологичный вид транспорта, и для здоровья полезно, и в квартиру можно занести
TarasB 20.02.2014 19:32 # 0
Я вроде бы уже упоминал, что мои контейнеры не имеют аналога в СТЛ, и только поэтому и писались.
Stertor 20.02.2014 19:34 # −2
В ответ на это нужно сказать что-нибудь резкое.
defecate-plusplus 20.02.2014 19:38 # +4
в с++ с бустом штук 30 точно наберётся (а то, может, и того больше)
и только Тарасу всё мало, нам нужны велосипеды с треугольными колёсами! как же мы раньше жили без них? надо ещё поддрочить и поднатужиться, а потом ныть, бля как же так, почему мой треугольный велосипед падает на пятиугольных шоссе!
хотя нет, продолжайте
TarasB 20.02.2014 20:04 # +2
defecate-plusplus 21.02.2014 10:01 # +2
TarasB 21.02.2014 10:16 # +3
laMer007 21.02.2014 02:50 # 0
bormand 20.02.2014 18:56 # +1
laMer007 21.02.2014 02:43 # 0
Konardo 21.02.2014 10:28 # −2