it-place.net > Уроци > C-Cplusplus
Не сте регистриран! Регистрирайте се БЕЗПЛАТНО, за да използвате услугите на сайта!

   Рубрики
 
 
 
 

 Форуми
» SEO и оптимизация
» Всичко за PHP и Perl
» Всичко за C, C++ и .NET
» Всичко за Java и JSP
» Всичко за SQL и MySQL
» Всичко за XHTML и CSS
» Презентация на сайтове
 Виртуални функции и Виртуални класове
  1. Въведение
  2. Множествено наследяване
  3. Виртуални класове
     
Автор  eminem (01.03.2005 23:50)  съобщение до автора
Погледнат  4430 пъти  добави към любими
Оценка  добави коментар
Гласове  4  изпрати на приятел
Коментари  (1)  абонирай се за C-Cplusplus
    Страница 1 / 3

 



Полиморфизмът е свойство на член-функциите и се реализира с виртуални функции.
Той се състои в осигуряване възможността генерирания код да се държи по различен начин в зависимост от условия, определяни по време на изпълнението на програмата.
Идеята на тези функции се основава на  вида на свързването им (статично или ранно и съответно динамично или късно)
 
1.Статичното свързване на типа на обекта с извикваната член-функция става по време на компилацията и не се променя при изпълнение на програмата. Свързващият редактор замества имената на извикваните функции с конкретните им адреси.

Пример илюстриращ статично свързване

CODE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream.h>
class point
  
{ protected:
     
int x,y;
     
point(int a=0,int b=0) { x=a; y=b; }
     
void out() {cout<<”точка:”<<x<<” “<<y<<”n”; }
   }
;
class pointcol:public point
  
{ short color;
     
public:
     
pointcol(int a=0,int b=0,short cl=1):point(a,b)
        {
color=cl; }
     
void out()
        {
cout<<”оцветена точка:”<<x<<” “<<y<<”с цвят:”<<color<,”n”; }
   }
;
void main()
   {
point p(3,5),*adp=&p;
     
pointcol pc(8,6,2),*adpc=&pc;        [color=blue]//Резултати от изпълнение[/color]
     
adp->out();    [color=blue]//извиква се out на point[/color]    [color=red]точка:3 5[/color]
     
adpc->out();[color=blue]//извиква се out на pointcol[/color]    [color=red]оцветена точка:8 6 2[/color]
     
adp=adpc;    [color=blue]//по време на изпълнението[/color]
     
adp->out();    [color=blue]//но adp е point по време[/color]    точка:3 5
     
adpc->out();[color=blue]//на компилация[/color]            [color=red]оцветена точка:8 6 2[/color]
   }

 
2.Динамичното свързване на типа на обекта с извикваната член-функция е по време на изпълнение на програмата. При извикването на функция се задава само името, но не и конкретния адрес на прехода. Или по време на изпълнение се дава възможността за промяна на връзките между имена и адреси. Късното свързване се определя чрез думата virtual.
 
Пример илюстриращ динамично свързване

CODE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream.h>
class point
  
{ protected:
     
int x,y;
     
point(int a=0,int b=0) { x=a; y=b; }
     
virtual void out() {cout<<”точка:”<<x<<” “<<y<<”n”; }
   }
;
class pointcol:public point
  
{     short color;
     
public:
     
pointcol(int a=0,int b=0,short cl=1):point(a,b)
       {
color=cl; }
     
void out()    [color=blue]//също е virtual(с или без служебна дума)[/color
       {
cout<<”оцветена точка:”<<x<<” “<<y<<”с цвят:”<<color<,”n”;}
   }
;
void main()
   { 
point p(3,5),*adp=&p;
     
pointcol pc(8,6,2),*adpc=&pc;        [color=blue]//Резултати от изпълнение[/color]
     
adp->out();    [color=blue]//извиква се out на point[/color]    [color=red]точка:3 5[/color]
     
adpc->out();[color=blue]//извиква се out на pointcol[/color]    [color=red]оцветена точка:8 6 2[/color]
     
adp=adpc;    [color=blue]//по време на изпълнението[/color]
     
adp->out();    [color=blue]//adp е pointcol по време[/color]    [color=red]оцветена точка:8 6 2[/color]
     
adpc->out();[color=blue]//на изпълнение[/color]            [color=red]оцветена точка:8 6 2[/color]
   }


Или указател на базовия клас се използва за извикване на член-функции на производния  клас вместо едноименните (предефинирани) функции на базовия (последните са virtual).

Пример за извикване на член-функция на базата на динамичния тип на викащия обект

CODE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream.h>
class animal
  
{ protected:
     
int age;
     
public:
     
animal(): age(1) { }
     
virtual void [b]speak[/b]() { cout<<”Animal speaks.n”; }
   }
;
class dog:public animal
  
{ public:
     
void [b]speak[/b]() { cout<<”Baow.n”; }
   }
;
class cat:public animal
  
{ public:
     
void [b]speak[/b]() { cout<<”Meow.n”; }
   }
;
class pig:public animal
  
{ public:
     
void [b]speak[/b]() { cout<<”Grouch.n”; }
   }
;
void main()
   {
animal *a[4],*ptr;[color=blue]//масив от указатели към базов клас и указател[/color]
     
int choice;
     
for(int i=0;i<4;i++)
       {
cout<<”(1)dog (2)cat (3)pig:”;
         
cin>>choice;
         
switch(choice)
            {
case 1: ptr=new dog; break;    [color=blue]//ptr се свързва с обектите[/color]
            
case 2: ptr=new cat; break;    [color=blue]//по време на изпълнение[/color]
             
case 3: ptr=new pig; break;
             
default:ptr=new animal;
           
}
         
a[i]=ptr;
      
}
     
for(i=0;i<4;i++) a[i]->speak();   
  
}

Резултати от изпълнение

(1)dog(2)cat(3)pig:1
(1)dog(2)cat(3)pig:2
(1)dog(2)cat(3)pig:3
(1)dog(2)cat(3)pig:4
Baow.
Meow.
Grouch.
Animal speaks.


speak е virtual функция и ще се извиква в зависимост от това къде сочи указателя в момента на изпълнение.

  • При наличие на виртуална функция – деструкторът трябва да е виртуален.
  • Конструкторът не може да бъде виртуален.
  • Ако е предефинирана виртуална функция, но с друг брой на параметрите, то това е друга функция и няма динамично свързване с нея.
  • Виртуалните функции  могат да са приятелски на други класове.



  Следваща страница >> 


Ключови думи: c C++ виртуална функция виртуален клас програма указател обект


Още уроци от тази рубрика


 
  • Подобни теми от myLinks
 

 1 посетител чете този урок (0 потребители и 1 гост)  
Активни потребители: ---
   
  

Еmail  
 

Не мисля, че може да се говори за "виртуални класове"  - правилният термин е "виртуално наследяване". И наистина ако се вгледаме в дефиницията на самия клас base, то там никъде около ключовата дума class не присъства virtual. Виртуалността в случая е свойство на самото наследяване.

  Izida на 12.09.2006 17:37

 

 
  • Интересно от Софтуер
 



IT-PLACE.NET © 2004 - 2008