- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
class SmoothingModeManager
{
public:
SmoothingModeManager(Context* context, Gdiplus::SmoothingMode mode = Gdiplus::SmoothingModeHighQuality);
virtual ~SmoothingModeManager();
protected:
Context* context_;
};
////////////////////////
SmoothingModeManager::SmoothingModeManager(Context* context, Gdiplus::SmoothingMode mode)
: context_(context)
{
context_->getCanvas()->SetSmoothingMode(mode);
}
SmoothingModeManager::~SmoothingModeManager()
{
context_->getCanvas()->SetSmoothingMode(Gdiplus::SmoothingModeNone);
}
Инициализируем класс и контекст со сглаживанием до конца метода.
Налицо не говнокод, а недостаток понимания.
Даже укоротить это до context_->smoothingMode(bool) и то понятнее и удобнее. И пусть низкоуровневые товарищи поправят, но вроде как вызвать метод два раза побыстрее, чем создавать для этого экземпляр класса.
Хотя это тоже вопрос - если этот класс на стеке, то тут уже надо мерять.
И еще вопрос в том, как компилятор на это посмотрит. Если соптимизирует - то вообще пофигу.
Подход неправильный.
Если развить эту мысль - то зачем вообще использовать языки высокого уровня? Лучше просто потребовать от программиста быть повнимательнее. И пусть в машинных кодах программит.
> А то потом непонятно почему начинают отрисовываться части со сглаживанием и без.
Заворачивание функций в класс как раз и гарантирует, что при деструкции объекта в обязательном порядке будет вызвана функция, отключающая сглаживание. В результате неразберихи становится гораздо меньше, чем если требовать от программиста вызвать отключалку сглаживания вручную (то return из функции неожиданный сработал, то эксепшен пришел, то программист в чужом коде не разобрался).
> И пусть низкоуровневые товарищи поправят, но вроде как вызвать метод два раза побыстрее, чем создавать для этого экземпляр класса.
Напомню, что речь идет о GUI. О каком-таком "быстрее" мы говорим? :) Пара сэкономленных машинных команд - это ничто.
Создание экземпляра данного класса на стеке - это две операции:
1. Сохранить указатель на контекст по адресу в стеке
2. Вызвать метод по указателю.
Область памяти под объект выделяется в кадре стека - это бесплатно с точки зрения накладных расходов.
Итак, от "ручного" вызова функции наш объект отличается фактически только одним-единственным присваиванием. Вы ради этой экономии будете заставлять программистов отслеживать парность вызовов по всему коду?
по моему тут все заинлайнится... а если указатель на контекст сделать константным, то и на стеке ничего не будет...
и виртуальный деструктор не нужен...
Даже вызов деструктора любой более-менее вменяемый компилятор оптимизирует в обычный call.
Кто-то такое сказал? const никогда не влияет на оптимизацию.
А вообще приведи хоть один дизасемблерный листинг, где из-за const произошла оптимизация? Небывает такого.
int a = 5;
const int b = 5;
printf( "%d\n", a + 5 );
printf( "%d\n", b + 5 );
Ассемблерный код:
movl a, %eax
addl $5, %eax
movl %eax, 4(%esp)
movl $.LC0, (%esp)
call printf
movl $10, 4(%esp)
movl $.LC0, (%esp)
call printf
В первом случае - честное вычисление, во втором - константа вычислена на этапе выполнения.
В случае с константными членами класса с С++, конечно, не все так прямолинейно. При создании объекта на стеке под константный мембер будет отведено место. Но тем не менее кое-какие оптимизации возможны и в этом случае (особенно если класс шаблонный).
В свете этой радости использованный компилятор, уверяю вас, абсолютно не важен.
А const ставить милионы раз. На лицо не оптимальность принятого решения. :)
профессионализм как раз заключается в умении писать код а не выбирать компиляторы...
;p
Это признак непрофессионализма, как совершенно верно заметил pushkoff. Отказ от расстановки const - это прежде всего отказ от документирования собственного кода. Нет const - нет сведений о том, можно ли изменять значение в данном месте кода или нет. Меньше сведений о коде - больше работы придется сделать тем, кто будет поддерживать твой код после тебя.
Не говоря уже о том, что надеяться на интеллектуальность компилятора там, где он проявлять интеллект вовсе даже не обязан - детский сад.
Обязан. :)
>Типа, компилятор должен сам разобраться, где тут что, и оптимизировать соответственно.
Как признак оптимизации const я раставлять не обязан. Если глупый компилятор соптимизирует мне то, что помечено, как const, а я потом это место const_cast'ом запаганю, то это исключительно глупость компилятора. Если не понятно, то могу привести пример.
>const - это прежде всего отказ от документирования собственного кода
Я где-нибудь сказал, что их не ставлю? Я сказал, что это не имеет отношение к оптимизации.
вот твой предидущий пост http://govnokod.ru/2657