КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Class base
Void main(void) Class base { public: virtual void vfunc (int i) { printf(" base::i = %d",i); }; }; class derived1: public base { public: void vfunc (int i) { printf(" der1::i = %d",i); }; }; class derived2: public base { public: void vfunc (int i) { printf(" der2::i = %d",i); }; }; { base B, *bp = &B; derived1 D1, *dp1 = &D1; derived2 D2, *dp2 = &D2; bp->vfunc(1); // Печатает: base::i = 1 dp1->vfunc(2); // Печатает: der1::i = 2 dp2->vfunc(3); // Печатает: der2::i = 3 bp = &D1; bp->vfunc(4); // Печатает: der1::i = 4 bp = &D2; bp->vfunc(5); // Печатает: der2::i = 5 } Заметим, что доступ к функциям vfunc() организован через указатель bp на базовый класс. Когда он принимает значение адреса объекта базового класса, то вызывается функция из базового класса. Когда указателю присваиваются значения ссылок на объекты производных классов &D1, &D2, выбор соответствующего экземпляра функции определяется именно объектом. Таким образом, интерпретация каждого вызова виртуальной функции через указатель на базовый класс зависит от значения этого указателя, то есть от типа объекта, для которого выполняется вызов. Для не виртуальной функции ее вызов через указатель интерпретируется в зависимости от типа указателя. Виртуальными могут быть не любые функции, а только нестатические компонентные функции какого-либо класса. После того как функция определена как виртуальная, ее повторное определение в производном классе (с тем же самым прототипом) создает в этом классе новую виртуальную функцию, причем спецификатор virtual может не использоваться. В производном классе нельзя определять функцию с тем же именем и с тем же набором параметров, но с другим типом возвращаемого значения, чем у виртуальной функции базового класса. Это приводит к ошибке на этапе компиляции. Если в производном классе ввести функцию с тем же именем и типом возвращаемого значения, что и виртуальная функция базового класса, но с другим набором параметров, то эта функция производного класса не будет виртуальной. В этом случае с помощью указателя на базовый класс при любом значении этого указателя выполняется обращение к функции базового класса (несмотря на спецификатор virtual и присутствие в производном классе похожей функции). Рассмотрим это на примере: // особенности виртуальных функций # inclube <stdio.h> { public: virtual void f1(void) { printf(" base::f1"); }; virtual void f2(void) { printf(" base::f2"); }; virtual void f3(void) { printf(" base::f3"); }; }; class derived: public base { public: void f1(void) { printf(" der::f1"); }; // виртуальная //int f2(void){ printf(" der::f2"); }; // ошибка в типе void f3(int i) {printf(" der::f3:%d",i);}; //невиртуальная };
Дата добавления: 2014-01-13; Просмотров: 540; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |