1 frag / 2 deaths
> Но вообще я не могу понять, на кой это надо.
Практический пример: рендер текста с разным выравниванием и свойствами без указания их через параметры.
Хочу чтобы можно было так:
Font->printf("health: %d", health);
И вот так:
Font->printf("health: %d", health).AlignRight();
Основная идея - главное действие идет в цепочке первым, а следом навешиваются разные модификаторы по желанию.
Vitorio
> главное действие идет в цепочке первым, а следом навешиваются разные
> модификаторы по желанию.
А почему ты предлагаешь нелогичые конструкции? Я читаю как "сначала выводим, потом двигаем влево". А потом висну "как можно двигать, если уже вывели".
Ну или хотя бы
Font->Message("health: %d", health).AlignLeft( ).Print( )?
Vitorio
> Font->printf("health: %d", health).AlignLeft();
> Основная идея - главное действие идет в цепочке первым, а следом навешиваются
> разные модификаторы по желанию.
паттерн называется "атомарный стрим".
суть идеи:
первый вызов цепочки порождает временный объект-аккумулятор.
который накапливает все "изменения".
когда цепочка завершается,
этот временный объект разрушается.
в деструкторе запускается процедура фиксации
всех накопленных изменений.
пример:
https://rextester.com/DNDVO55765
#include <iostream> #include <sstream> struct Font; struct Accumulator { Accumulator(const Accumulator&) = delete; Accumulator( Accumulator&&) = delete; Accumulator& operator=( const Accumulator&) = delete; Accumulator& operator=( Accumulator&&) = delete; Accumulator( Font& owner, const char* text) : ss( ) , aglin_left( false) , owner( &owner) { ss << text; } Accumulator& AlignLeft( ) { aglin_left = true; return *this; } ~Accumulator( ); std::stringstream ss; bool aglin_left = false; Font* owner; }; struct Font { Accumulator printf( const char* text) { return { *this, text }; } void commit( const Accumulator& acc) { if( acc.aglin_left) std::cout << "[AlignLeft] "; std::cout << acc.ss.str( ) << '\n'; } }; Accumulator::~Accumulator( ) { this->owner->commit( *this); } int main( ) { Font font; font.printf( "ololo").AlignLeft( ); }
1 frag / 2 deaths
> Я читаю как "сначала выводим, потом двигаем влево". А потом висну "как можно
> двигать, если уже вывели".
Ты так читаешь потому, что тебя так научили читать. Мой вариант идет вразрез с известными тебе правилами, но и его тоже можно принять за правило:) И Ц++ может и такой изврат, что доказывает вариант от Faceroll :)
Вариант с финализирующим print получается длиннее на 1 метод...
Upd:
Kartonagnick, спасибо! Буду курить код!
Vitorio
> Ты так читаешь потому, что тебя так научили читать.
?овелан аварпс ьшеатич ыт ,ондал аД
Vitorio
> Font->printf("health: %d", health).AlignRight();
Не надо выдумывать никакую обратную логику.
С++ умеет в процедурку и в ООП, значит этим и надо пользоваться.
То, что вы хотите, делается примерно так:
class Font {
public:
Text printf(char* txt, args ...);
};
class Text {
public:
Text& AlignRight() {
//some magic;
return *this;
}
~Text() { std::cout << _message; };
private:
char* _message;
};
Хотя, лучше, конечно, печатать не в деструкторе, а отдельным методом, как уже было предложено выше - так код будет гораздо понятнее для других людей.
Помнится, _Winnie так предлагал спрайты рисовать:
https://users.livejournal.com/-winnie/229311.html
Vitorio
Ты наркоман, прочь от клавиатуры, иди мети дворы.
Рабочая логика в деструкторе плохо пахнет.
1 frag / 2 deaths
> Рабочая логика в деструкторе плохо пахнет.
Всмысле? У того же smart_ptr основная работа - это подчищать за другими мусор и она в деструкторе делается.
1 frag / 2 deaths
> Рабочая логика в деструкторе плохо пахнет.
вы это так пишите, будто бы рабочая логика в деструкторе
чем то принципиально отличается от рабочей логики ещё где нибудь.
=A=L=X=
Как же вы бесите, все мои старания в прах уничтожили, я и так и сяк старался найти формулировку, что-то типа "задач, не относящихся к освобождению ресурсов" или хрен знает ещё как это назвать, нет же, всё равно вы докопаетесь чисто в лоб.
Kartonagnick
> вы это так пишите, будто бы рабочая логика в деструкторе
> чем то принципиально отличается от рабочей логики ещё где нибудь.
Точка вызова деструктора зависит даже от того, вернёт ли функция конст реф, или просто реф, как вообще на неё можно закладываться?
=A=L=X=
Да ты вообще не напрягся блин. Нет чтоб на секунду хоть подумать "ну по любому же он знает про смартпоинтеры, что же он имел в виду", нет, ты сходу ляпаешь.
В деструкторах есть проблемы с исключениями, но так как геймдевелоперы не используют исключения то все ок :trollface
Тема в архиве.