
- •Int main (int argv, char * argc[])
- •Int main (int argv, char * argc[]);
- •Void func1 ( a& a );
- •Void func2 ( a a );
- •Void swap (int a, int b)
- •Void swap (int &a, int &b)
- •Int Year;
- •Int Month;
- •Создание и уничтожение объектов в c#. Интерфейс iDisposable и освобождение ресурсов.
- •Int m_nYear;
- •Int m_nMonth;
- •Int m_nDay;
- •Inline int even(int X)
- •System.Collections.Generic.IEqualityComparer(Of t)
- •Public:
- •Virtual int GetHashCode()
- •Ассоциативные и последовательные контейнеры stl. Понятие итератора. Общие свойства контейнеров. Особенности и применение каждого из контейнеров.
- •// Do what you need with element using *I ;
- •Vint v1, v2(100);
- •Vint v3(v2.Begin(), --v2.End());
- •Sort(V.Begin(), V.End());
- •Setstr s, s2;
- •Использование контейнеров stl. Методы резервирования памяти контейнерами stl. Требования к элементам контейнеров.
- •C.Insert(s);
- •Обобщенные контейнеры .Net. Интерфейс iEnumerable и оператор foreach. Сравнение обобщенных контейнеров и ArrayList.
- •IEnumerable - интерфейс
- •Int m_nCount;
- •Int sprintf(buffer, format-string[, argument...]); char *buffer;
- •Язык регулярных выражений. Классы символов, исчислители, последовательности и несимвольные подстановки. Валидация email адреса при помощи регулярных выражений.
- •If (rx.IsMatch(testString))
- •Язык регулярных выражений. Классы символов, исчислители, альтернативы и подстановки. Применение регулярных выражений для изменения формата даты.
- •If (rx.IsMatch(testString))
- •Язык регулярных выражений. Классы символов, исчислители, альтернативы и последовательности. Выбор всех атрибутов href из html текста.
- •If (rx.IsMatch(testString))
- •Обработка исключений. Правила перехвата исключений. Назначение системы обработки исключений. Для чего система обработки исключений не предназначена.
- •Int operator / (cMyClass o, int I) {
- •Void main() {
- •Наследование, иерархии классов и обобщенная обработка данных. Чистый полиморфизм (полиморфизм виртуальных методов). Интерфейсы и абстрактные классы.
- •Int m_nCount;};
- •Int m_nCount;
- •Int m_nCount;
- •Int m_nCount;
- •Virtual string Iam(){return "furniture";}
- •Рекурсия. Рекуррентные структуры данных и рекурсивные алгоритмы. Алгоритм просмотра дерева каталогов файловой структуры.
- •Рекуррентное определение выражений. Алгоритм анализа и вычисления выражений (программа ”калькулятор”).
Virtual string Iam(){return "furniture";}
Теперь пример сработает как ожидалось!
Почему это произошло? Все дело в так называемом “позднем связывании”. Вспомним еще раз, что происходит при компиляции и сборке программы. Компилятор готовит отдельные модули, затем компоновщик связывает эти модули в единую программы. Там где стоит вызов Iam() подставляется адрес конкретной функции. На момент компоновки об этой функции известно только что это метод CFurniture, его-то адрес и будет стоять в результирующей программе. Поэтому, какие объекты фактически были добавлены в список не играет роли. Это так называемое “статическое связывание”.
При позднем связывании компилятор “знал”, что вызывается виртуальный метод. Поэтому нельзя подставлять при вызове Iam вызов конкретной функции, а нужно подставить код поиска ее в таблице виртуальных методов. У каждого класса имеется собственная таблица виртуальных методов. В нее помещаются все методы, отмеченные как virtual. Если потомок перекрывает виртуальный метод, то в таблице потомка указывается иной адрес этого метода.
Таким образом, поиск нужной функции выполняется во время исполнения программы:
- У объекта выясняется адрес таблицы виртуальных методов его класса.
- В этой таблице ищется адрес соответствующего метода;
- Найденный метод вызывается.
Это и есть позднее связывание.
Так полиморфизм позволил продвинуться к разработке обобщенных программ, которые могут работать с абстрактными понятиями, которые обобщают множество конкретных типов.
Резюме.
Полиморфизм – важное средство объектно-ориентированного программирования. Основное его предназначение – обеспечить абстракции понятий и операций, которые могут различаться для конкретных классов.
Важнейший вид полиморфизма – полиморфизм виртуальных методов. Он позволяет хранить и обрабатывать специфическим для каждого класса образом объекты одной иерархии классов в одном контейнере. Перечислим, как это делается:
- методы, различающиеся для потомков, в классе предке объявляются виртуальными;
- указатели на динамически созданные объекты помещаются в контейнер для указателей на старший класс иерархии.
В этом случае, для каждого объекта будут вызываться методы именно его фактического класса, а не методы предка.
Интерфейсы и абстрактные классы
Что если мы хотим объявить класс, от которого будет построена целое семейство потомков, но сам класс реализовывать нет смысла – объекты такого типа бессмысленны и создаваться не могут. Примерами могут быть классы CFigure и CFurnuture. Невозможно нарисовать фигуру вообще или предмет мебели. Это всегда их конкретизация, прямоугольник, стол и т.п.
Для отражения такой картины в C++ могут объявляться абстрактные методы. Вот пример объявления.
class CFigure {
public:
virtual void Draw(CWnd *hWnd) = 0;
};
Т.е. мы знаем, что метод Draw будет переопределен в каждом классе – потомке CFigure. Поэтому он объявлен как virtual. А на то, что его реализация отсутствует указывает = 0 после объявления.
Классы, у которых нет полей данных, а все методы виртуальные и абстрактные называются абстрактными классами или интерфейсами. Интерфейсам не нужны конструкторы и деструкторы – объекты этого типа создаваться не могут. Их единственная роль – задать интерфейс использования потомков.