28 сентября 2006

Calling base class virtual method

Предположим, у нас есть иерархия классов:
class Base
{
public:
virtual void Do() { cout << "Base::Do()" << endl; }
virtual ~Base() {}
};

class Derived : public Base
{
public:
virtual void Do() { cout << "Derived::Do()" << endl; }
};
Класс Derived переопределяет метод Do(), и код, оперирующий объектом этого класса, при вызове Do() будет всегда вызвать Base::Do().

Даже если преобразовать указатель или ссылку на объект класса Derived к указателю или ссылке на Base, то будет вызываться Derived::Do() - за это отвечает таблица виртуальных функций или другой подобный механизм, встроенный в язык:
Derived d;
d.Do(); // Derived::Do()
Base& b = d;
b.Do(); // тоже Derived::Do()

А теперь вопрос: как вызвать Base::Do() для объекта типа Derived?

Во-первых, разберемся корректно ли это. По сути, void Base::Do() представляет собой void Do(Base* This), а void Derived::Do() представляет void Do(Derived* This). Так как можно легко преобразовывать Derived* к Base*, то есть вызов Base::Do() для Derived является корректным. Такой вызов часто используется при напимании методов унаследанного класса:
void Derived::DoSomething()
{
// do something
Base::Do();
// do something else
}
Прекрасно, "изнутри" Derived (то есть из методов самого Derived) мы можем вызывать Base::Do(), но как быть если нужно вызвать этот метод "снаружи"?

Оказывается, синтаксис такой:
Derived d;
d.Base::Do();

19 сентября 2006

Is "for each" possible with current C++?

Всем поклонникам C++ советую прочитать эту статью: Conditional Love: FOREACH Redux, написанную одним из C++-geek-ов - Эриком Ниблером из Boost Consulting.

Вы поймете какую радость приносит людям язык C++ с кучей своих недостатков и нереализованных в нем возможностей. Сможете ли Вы написать макрос FOREACH(item, container)? Будет ли он нормально работать с любыми контейнерами, в том числе и с rvalue? Возможно ли вообще его написать на современном C++ не дожидаясь выхода новых стандартов?

Полученный Эриком FOREACH, по-моему, представляет чисто академический интерес (зато какой интерес!). У меня и так время компиляции - узкое место, а с такими конструкциями мой компилятор вообще коньки отбросит наверно...

PS. А вообще эта статья про мой любимый условный оператор ?:

09 сентября 2006

Эволюция WinAPI

Каким образом нужно использовать ту или иную возможность WinAPI - сильно зависит от времени, когда она появилась. Если она была введена в Win3.1 - получите доступ через сообщения, если в Win2000 - через COM объекты. Полагаю, новые возможности Vista будут доступны только через .NET.

Пример - настройка combobox. Показывать в нем свои элементы можно давно, и реализовывается это через обработку сообщений (WM_DRAWITEM). Сделать собственное автодополнение и автозаполнение - сравнительно недавно, и делать это надо уже через написание COM-объекта (IAutoComplete). Новые возможности комбобокса, думаю будут доступны через managed code.