Sie sind auf Seite 1von 12

C++

Chapter 10: Virtual function

-----------------------------------------------------------------------Chapter Contents Object Pointers Dynamic Memory allocation: new and delete The this Pointer Virtual Function The Virtual table Virtual Destructor Pure Virtual function Early and Late Binding

-----------------------------------------------------------------------Object Pointers ust li!e any ordinary "ointer of any "rimiti#e data ty"e$ %e may ha#e object "ointers that "oint to some object& E'am"le: #include<iostream.h> #include<conio.h> class complex { private: int a,b; public: void getdata() { cout<< !nter real and img part ; cin>>a>>b; " void show() { cout<< #na$ <<a<< b$ <<b; " "; int main() { complex c%; complex &ptr; ptr$'c%; ptr(>getdata();

ptr(>show(); getch(); " (n the abo#e e'am"le$ )e created an object of ty"e com"le' and also declared a "ointer of ty"e com"le'& *ame of "ointer is "tr %hich is object "ointer as it can "oint to an object of ty"e com"le'& Pointer "tr stores address of object c+& )hen e#er members of object are accessed using object name %e need to use dot ,.o"erator$ but if members are to be accessed through "ointer name %e need to use arro% ,./- o"erator& (n the line "tr./getdata,-$ function getdata,- %ill %or! for the object "ointed to by "tr& Dynamic Memory allocation: new an delete 0un time memory can be allocated by using !ey%ord new and this allocated memory can be released using !ey%ord delete. E'am"le #include<iostream.h> #include<conio.h> void main() { clrscr(); int &p$ new int; )loat &*$ new )loat; &p$+; &*$,%.-+; cout<<.&p$.<<&p; cout<<.&*$.<<&*; delete p; delete *; getch(); " (n the abo#e "rogram Pointer " is used to store address of dynamically allocated int ty"e bloc! using !ey%ord ne%& Pointer 1 is used to store address of dynamically allocated float ty"e bloc! using !ey%ord ne%& (n 2 language %e dynamically allocate memory using "redefined functions malloc,or calloc,-$ here same functionality is done by !ey%ord ne%&

The only difference bet%een malloc and ne% is in former case %e ha#e to s"ecify the si3e of bloc! and in later case %e ha#e to mention name of data ty"e& Dynamically allocated memory can be accessed only through "ointers& Memory can be released using !ey%ord delete$ this is same as function free,-& *otice that delete releases the memory for s"ecified address& delete p; %ould not mean that " is released instead it means delete releases memory "ointed to by "& E'am"le #include<iostream.h> #include<conio.h> void main() { clrscr(); int &p$ new int/-0; &p$+; &(p1%)$%2; &(p12)$,,; &(p1,)$-+; )or(int i$3;i<$,;i11) cout<<.&(p1.<<i<<.)$.<<&(p1i); delete /0p; getch(); " (n the abo#e e'am"le )e created an array of 4 int bloc!s dynamically using !ey%ord ne%& *otice s1uare brac!ets after data ty"e int& This is used to mention si3ed of dynamic array& 5ddress of the first bloc! of array gets stored in "& 6ubse1uent instructions are used to store #alues in four bloc!s of array& 5t last %e use delete to release memory$ see its synta' carefully$ s1uare brac!ets needs to be mentioned before "ointer name& (t ma!es "ossible to release memory of all four bloc!s& E'am"le #include<iostream.h> #include<conio.h> class complex { private: int a,b; public: complex() {a$3; b$3;" void getdata() {

cout<< !nter real and img part ; cin>>a>>b; " void show() { cout<< #na$ <<a<< " "; void main() { clrscr(); complex &p$ new complex; p(>show(); p(>getdata(); p(>show(); delete p; getch(); " (n the abo#e e'am"le )e created object "ointer to store address of dynamically allocated memory for object of ty"e com"le'& 5s soon as object is created constructor is called& "./sho%,- dis"lay the #alues of a and b of this run time generated object& 6ubse1uent instructions are used to call other members of the class& 7ey%ord delete releases the memory of object "ointed to by "& !he this Pointer 288 "ro#ides a s"ecial in.build "ointer !no% as this "ointer& this "ointer is a local "ointer #ariable in e#ery member function& this "ointer needs no declaration (ts sco"e is limited to the member function& Friend functions are not member functions thus they do not ha#e this "ointer& 6tatic member functions do not ha#e this "ointer this "ointer is of ty"e of that class of %hich function is a member&

b$ <<b;

E'am"le #include<iostream.h> #include<conio.h> class complex { private: int a,b; public:

void getdata() { cout<< !nter real and img part ; cin>>a>>b; " void show() { cout<< #na$ <<a<< b$ <<b; " complex sumgreater(complex c) { i)((a1b) > (c.a1c.b)) return(&this); else return(c); " "; int main() { complex c%,c2,c,; c%.getdata(); c2.getdata(); c,$c%.sumgreater(c2); c,.show(); getch(); " (n the abo#e e'am"le Obser#e the member function sumgreater,-$ its job to return an object %hose sum of member #ariable is greater among t%o objects& (n the line c,$c%.sumgreater(c2); sumgreater,- function is called by object c+$ thus the address of c+ is "assed im"licitly to the member function sumgreater,-$ %hich is then recei#ed by "ointer this& )e also "asses an object c9 to function sumgreater,-$ %hich is recei#ed in object c& (f the sum of data stored in a and b of c+ is greater than the sum of data stored in a and b of c9, re"resented by c in sumgreater,-- then object c+ has to be returned& The "roblem is ho% to re"resent caller object c+ in function sumgreater,-& The "roblem is sol#ed by using this "ointer$ as this contains the address of c+$ :this is used to re"resent caller object ,that is c+ in our e'am"le-& Virtual "unction Before going through #irtual function %e need to understand fe% of the basic things&

(n inheritance$ let us assume there is a Base class and a Deri#ed class& *o% %e create a "ointer of base class in function main,-& 2onsidering this situation di#e in for de"th !no%ledge$ read the follo%ing t%o "oints: +- Base class "ointer can store address of base class object or can store address of Deri#ed class object& 9- (f Base "ointer contains address of Deri#ed class object$ %e can access only those members of Deri#ed class using Base "ointer %hich are inherited from Base class& E'am"le #include<iostream.h> #include<conio.h> class 4ase { public: void )un%() { cout<<.4ase 5lass, )un%().; " void )un2() { cout<<.4ase 5lass, )un2().; " "; class 6erived : public 4ase { public: void )un%() { cout<<.6erived 5lass, )un%().; " void )un2() { cout<<.6erived 5lass, )un2().; " "; void main() { clrscr(); 4ase &p; p$ new 4ase; p(>)un%(); ;;Base class #ersion is called p(>)un2(); ;;Base class #ersion is called delete p; p$ new 6erived; p(>)un%(); ;;Base class #ersion is called

p(>)un2(); ;;Base class #ersion is called delete p; getch(); " (f %e call fun+,- or fun9,- using Object of Deri#ed class using dot ,.- o"erator$ Deri#ed class #ersion of functions %ould be called& This is called function o#erriding ,see cha"ter <)e focus our discussion to access member using object "ointers only& (n the abo#e e'am"le if %e made base class #ersion of function #irtual by "refi'ing a !ey%ord #irtual then Base "ointer calls #ersion of function de"ends on address contained by Base "ointer& (f Base "ointer contains address of Base class object then function of Base class #ersion %ould be run and if Base "ointer contains address of Deri#ed class object then function of Deri#ed class #ersion %ould run& E'am"le #include<iostream.h> #include<conio.h> class 4ase { public: virtual void )un%() { cout<<.4ase 5lass, )un%().; " void )un2() { cout<<.4ase 5lass, )un2().; " "; class 6erived : public 4ase { public: void )un%() { cout<<.6erived 5lass, )un%().; " void )un2() { cout<<.6erived 5lass, )un2().; " "; void main() {

clrscr(); 4ase &p; p$ new 4ase; p(>)un%(); ;;Base class #ersion is called p(>)un2(); ;;Base class #ersion is called delete p; p$ new 6erived; p(>)un%(); ;;Deri#ed class #ersion is called p(>)un2(); ;;Base class #ersion is called delete p; getch(); " E'"lanation 5 #irtual function is al%ays a member of a class& 5 function can be made #irtual by using !ey%ord #irtual ,see fun+,- in Base class (t usually has a different functionality in Deri#ed class 5 function call is resol#ed at run time 6ee in abo#e e'am"le "./fun+,- is %ritten t%o times but they call different #ersions$ former is a call to Base class #ersion of fun+,- and later is call to Deri#ed class #ersion& 6ince both the calls loo! ali!e it is "olymor"hism& (t is %orth mentioning here that #irtual function mechanism is #alid for functions sharing same "rototy"e but different definitions$ one in Base class and other in Deri#ed class& (f functions ha#e same name but #ary in arguments$ #irtual !ey%ord losses its effect& (f Base class contain any #irtual function$ it is not mandatory to redefine in Deri#ed class& !he Virtual table To im"lement #irtual functions$ 288 uses a s"ecial form of late binding !no%n as the #irtual table& The #irtual table is a loo!u" table of functions used to resol#e function calls in a dynamic;late binding manner& The #irtual table sometimes goes by other names$ such as =#table>$ =#irtual function table>$ =#irtual method table>$ or =dis"atch table>& E#ery class that uses #irtual functions ,or is deri#ed from a class that uses #irtual functions- is gi#en it?s o%n #irtual table& This table is sim"ly a static array that the com"iler sets u" at com"ile time& 5 #irtual table contains one entry for each #irtual function that can be called by objects of the class& Each entry in this table is sim"ly a function "ointer that "oints to the most.deri#ed function accessible by that class& The com"iler also adds a hidden "ointer to the base class$ %hich %e %ill call :@@#"tr& :@@#"tr is set ,automatically- %hen a class instance is created so that it "oints to the #irtual table for that class&

(t ma!es each class object allocated bigger by the si3e of one "ointer& (t also means that :@@#"tr is inherited by deri#ed classes$ %hich is im"ortant& )hen a class object is created$ :@@#"tr is set to "oint to the #irtual table for that class& For e'am"le$ %hen a object of ty"e Base is created$ :@@#"tr is set to "oint to the #irtual table for Base& )hen objects of ty"e Deri#ed is constructed$ :@@#"tr is set to "oint to the #irtual table for Deri#ed )hen these #irtual tables are filled out$ each entry is filled out %ith the most. deri#ed function an object of that class ty"e can call&

Virtual Destructor Li!e constructors$ destructors also non inheritable elements of class& 0emember$ 2onstructors can not be made #irtual$ but destructors can be& 5lthough 288 "ro#ides a default destructor for your classes if you do not "ro#ide one yourself$ it is sometimes the case that you %ill %ant to "ro#ide your o%n destructor ,"articularly if the class needs to deallocate memory-& Aou should al$ays ma!e your destructors #irtual if you?re dealing %ith inheritance& E'am"le ,%ithout #irtual destructor#include<iostream.h> #include<conio.h> class 4ase { public: void )un%() { cout<< #n7ou are in class 4ase and )un%() ; " 84ase() { cout<< 7ou are in 4ase 6estructor ; " "; class 6erived: public 4ase { int a,b; public: void )un%() 99function o#erriding { cout<< #n7ou are in class 6erived and )un%() ; " 86erived() { cout<< 7ou are in 6erived 6estructor "; int main() { cout<< 7ou are in main() ; { 4ase &p$new 6erived; ; "

p(>)un%(); delete p; " getch(); " Out"ut: Aou are in main,Aou are in class Base and fun+,Aou are in Base Destructor "B To e'ecute Deri#ed class constructor as %ell as Base class constructor you need to ma!e destructor #irtual& Aou can obser#e that only Base class destructor e'ecutes at the line delete

E'am"le ,)ith Virtual destructor#include<iostream.h> #include<conio.h> class 4ase { public: void )un%() { cout<< #n7ou are in class 4ase and )un%() ; " virtual 84ase() { cout<< 7ou are in 4ase 6estructor ; " "; class 6erived: public 4ase { int a,b; public: void )un%() 99function o#erriding { cout<< #n7ou are in class 6erived and )un%() ; " 86erived() { cout<< 7ou are in 6erived 6estructor "; int main() { cout<< 7ou are in main() ; { 4ase &p$new 6erived; p(>)un%(); delete p; " ; "

getch(); " Out"ut: Aou are in main,Aou are in class Base and fun+,Aou are in Deri#ed Destructor Aou are in Base Destructor

Pure Virtual function 5 function in a class can be made #irtual by %riting !ey%ord #irtual and if it has no definition it is called "ure #irtual function& Pure #irtual function is also !no%n as do.nothing function& 6ynta': #irtual return type function name%&'0( *otice the s"ecial %ay of assigning C$ it is actually not assignment but just to mention com"iler that this function has no body that is no definition& (f a class is containing "ure #irtual function: 2lass is !no%n as abstract class$ that is %e can not create its object To access member of this class %e need to define its deri#ed class since %e can not create its object& Deri#ed class of abstract class must either redefine "ure #irtual function or re. declare it again "ure #irtual function& )arly an *ate +in in, )hen a "rogram is com"iled$ the com"iler con#erts each statement in your 288 "rogram into one or more lines of machine language& Each line of machine language is gi#en it?s o%n uni1ue se1uential address& This is no different for functions D %hen a function is encountered$ it is con#erted into machine language and gi#en the ne't a#ailable address& Thus$ each function ends u" %ith a uni1ue machine language address& +in in, refers to the "rocess that is used to con#ert identifiers ,such as #ariable and function names- into machine language addresses& 5lthough binding is used for both #ariables and functions& Early Binding )arly bin in, ,also called static binding- means the com"iler is able to directly associate the identifier name ,such as a function or #ariable name- %ith a machine address&

)hen the com"iler encounters a function call$ it re"laces the function call %ith a machine language instruction that tells the 2PE to jum" to the address of the function& Those decisions ta!en at com"ile time sa#es e'ecution time$ but such "rograms are not fle'ible& Function o#erloading and o"erator o#erloading are e'am"le of early binding& Late Binding (n some "rograms$ it is not "ossible to !no% %hich function %ill be called until runtime ,%hen the "rogram is run-& This is !no%n as late bin in, ,or dynamic binding-& (n 288$ one %ay to get late binding is to use function "ointers& Those decisions ta!en at run time are ta!ing e'tra e'ecution time$ but "ro#ide greater fle'ibility to the user& Virtual function is an e'am"le of late binding&

Das könnte Ihnen auch gefallen