- 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;
}
};
Смысла в этом не очень вижу, разве что как обёртку над PIMPL указателями, чтобы не писать свои деструктор и оператор присваивания.
Куда интереснее была бы идея COW указателя.
А как он узнает, что в объект кто-то писал? А по любой неконстантной разадресации делать detach() - не комильфо.
Хотя идея далеко не благая, но в ад всё равно ведёт.
Ну нахуя? Там и так по умолчанию генерится адекватный оператор присваивания и копирующий конструктор...
Писать деструкторы, операторы присваивания и копикторы/мувикторы приходится только в низкоуровневых классах. В остальных случаях почти всегда хватает дефолтовых.
про классы, в которых не надо писать свою логику в деструкторе, и так ясно, не про них речь
Правда на 90% в них вообще T(T) не нужен, но опять же - а чего это я должен руками банить обоих, и T(T) и =(T)?
Скажите, а boost::noncopyable не может спасти гиганта мысли?
Ну это само собой: откаты транзакций (RAIIшная обертка над транзакцией), тот же std::lock_guard (RAIIшная обертка над lock/unlock).
Но это же все низкоуровневые классы, которые пишутся один раз...
> пометить объект - снять пометку с объекта
Можно пример из практики?
Долго рассказывать, но попробую.
Задача такая, есть дохрена большой, допустим, граф, дохренища большой, размером 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) моё решение брутально и тупое, но я пока не скажу
В postgres есть аналогичная проблема с номерами транзакций. Если ты выключишь autovacuum, который помимо сжатия таблиц меняет айдишки слишком старых транзакций на специальное число (то ли 0 то ли -1), которое заведомо меньше любых реальных xid'ов, то через 2^31 транзакций кровь-кишки-полбазы-пропало.
> Переубийство, я считаю.
Если у тебя несколько потоков и более-менее статичный граф - то других вариантов походу и нет. Ибо если ставить метки в самом графе - придется блочить его, что убьет весь профит от потоков.
> моё решение брутально и тупое, но я пока не скажу
Набиваешь в какой-нибудь контейнер, умеющий вставку за O(1) объекты, которые в деструкторе снимают метки с соотв. узлов графа?
Ёпт, ты догадливый.
Контейнер этот - тарасомассив. Размер графа известен, так что сколько памяти выделить - тоже известно.
Осталось только таскать ссылку на этот массив во всех методах.
а Тарас тебе что, сраный быдлокодер-формошлёп?
велосипед - вообще самый экологичный вид транспорта, и для здоровья полезно, и в квартиру можно занести
Я вроде бы уже упоминал, что мои контейнеры не имеют аналога в СТЛ, и только поэтому и писались.
В ответ на это нужно сказать что-нибудь резкое.
в с++ с бустом штук 30 точно наберётся (а то, может, и того больше)
и только Тарасу всё мало, нам нужны велосипеды с треугольными колёсами! как же мы раньше жили без них? надо ещё поддрочить и поднатужиться, а потом ныть, бля как же так, почему мой треугольный велосипед падает на пятиугольных шоссе!
хотя нет, продолжайте