Presentation is loading. Please wait.

Presentation is loading. Please wait.

Lecture 11: Virtual Function and Pure Virtual Function

Similar presentations


Presentation on theme: "Lecture 11: Virtual Function and Pure Virtual Function"— Presentation transcript:

1 Lecture 11: Virtual Function and Pure Virtual Function
Object Oriented Programming (C++) ( Bilingual Teaching) Lecture 11: Virtual Function and Pure Virtual Function

2 Question 1 class A{ int x; public: A(int a) {x=a;} };
///////////////////////////////// class B{ int x,y; B(int a, int b) {x=a;y=b;} class C:public A, B{ int z; public: C( int a, int b, int c, int d) { A(a); B(b,c); z=d;} …. }; Whether the program is wrong and how to correct it?

3 Question 2 class B: public A{ class A{ int b; int a; public: public:
void fun( ); }; class A{ int a; public: void fun( ); }; Judgment: Ambiguity? B b; b.fun( );

4 Question 2 (cont.) class X{ public: void fun1( ); …… }; class Y{
class Z: public X, public Y{ public: void fun( ); …… }; Judgment: Ambiguity? Z z; z.fun1( );

5 Main Contents Virtual base class Rules of assignment in inheritance
Virtual functions Pure virtual functions and Abstract Classes

6 Virtual base class Declaration:
class derivative : virtual <access> base {//….}; The reason: If we have multi-inherits from different base classes and these classes are derived from the same base class, it will produce many copies of the same base class. In this case, it will lead to the waste of memory, and ambiguity.

7 Example 1 class A{ public: void showa(){cout<<"A"<<endl;}
}; class B: public A{ void showb(){cout<<"B"<<endl;} class C: public A{ void showc(){cout<<"C"<<endl;} class D: public B, public C{ public: void showd(){cout<<"D"<<endl;} }; void main() { D d; d.showa(); }

8 class structure: void main() { D d; // d.showa(); error d.B::showa();
d.C::showa(); } A B C D

9 Example 2 Name Age Sex Depart. Job Spec. Num. Person Person person
Worker Worker Student person Work-Stu Student The structure of the common derived class and the form of the storage for the member data.

10 class person{ char *Name; int Age; char Sex; public: person(char * name="0", int age=0, char sex='0'); person(person&); ~person(); char *GetName(){return Name;} int GetAge(){return Age;} char GetSex(){return Sex;} void show(); };

11 class student : virtual public person
{ char *Department; char *Speciality; int Number; public: student(char *, int , char , char*, char *, int); student(char*, char *, int); student(student &);

12 ~student() { delete []Department; delete []Speciality; } void SetDep(char *); void SetSpec(char *); void SetNum(int num){ Number=num;} char *GetDep() {return Department;} char *GetSpec(){return Speciality;} int GetNum(){ return Number;} };

13 student ::student(char. name, int age, char sex, char. dep, char
student ::student(char *name, int age, char sex, char *dep, char *spe, int num):person(name, age,sex) { Department=new char[strlen(dep)+1]; strcpy(Department,dep); Speciality=new char[strlen(spe)+1]; strcpy(Speciality,spe); Number=num; }

14 student ::student(char *dep, char *spe, int num)
{ Department=new char[strlen(dep)+1]; strcpy(Department,dep); Speciality=new char[strlen(spe)+1]; strcpy(Speciality,spe); Number=num; }

15 student::student(student &stu):person(stu)
{ Department=new char[strlen(stu.Department)+1]; strcpy(Department,stu.Department); Speciality=new char[strlen(stu.Speciality)+1]; strcpy(Speciality,stu.Speciality); Number=stu.Number; }

16 void student::SetDep(char *dep)
{ if(Department) delete Department; Department=new char[strlen(dep)+1]; strcpy(Department,dep); } void student::SetSpec(char *spe) if(Speciality) delete Speciality; Speciality=new char[strlen(spe)+1]; strcpy(Speciality,spe);

17 class Worker: virtual public person{
char *Department; char *Job; public: Worker(char *, int , char , char*, char *); Worker(char*, char *); Worker(Worker &);

18 ~ Worker() { delete []Department; delete []Job; } void SetDep(char *); void SetJob(char *); char *GetDep() {return Department;} char *GetJob(){return Job;} };

19 Worker :: Worker(char. name, int age, char sex, char. dep, char
Worker :: Worker(char *name, int age, char sex, char *dep, char *job):person(name, age,sex) { Department=new char[strlen(dep)+1]; strcpy(Department,dep); Job=new char[strlen(job)+1]; strcpy(Job,job); } Worker :: Worker(char *dep, char *job)

20 Worker :: Worker(Worker &w):person(w)
{ Department=new char[strlen(w.Department)+1]; strcpy(Department,w.Department); Job=new char[strlen(w.Job)+1]; strcpy(Job,w.Job); } void Worker ::SetDep(char *dep) if(Department) delete Department; Department=new char[strlen(dep)+1]; strcpy(Department,dep);

21 void Worker ::SetJob(char *job)
{ if(Job) delete Job; Job=new char[strlen(job)+1]; strcpy(Job,job); } class Work_Stu: public Worker, public student{ public: Work_Stu(char *name, int age, char sex, char *depw, char *job, char *deps, char *spec, int num):person(name, age, sex),Worker(depw, job), student(deps, spec, num) { } Work_Stu(Work_Stu &ws):Worker(ws), student(ws) { } };

22 void main() { Work_Stu ws("Wang Ping", 23, 'f', “Manager office", “Secretary“, "Computer Dep.", "Computer Software", 12345); cout<<ws.GetName()<<'\t'<<ws.GetAge()<<'\t'<<ws.GetSex()<<endl; cout<<ws.Worker::GetDep()<<'\t'<<ws.GetJob()<<endl; cout<<ws.student::GetDep()<<'\t'<<ws.GetSpec()<<'\t'<<ws.GetNum()<<endl; } Result: Wang Ping f Manager office Secretary Computer Dep. Computer Software

23 Name Age Sex Departw. Job Departs Spec Num. Person Worker Student Work-Stu The structure of the derived class from virtual base class.

24 Virtual base class for example1
class A{ public: void showa(){cout<<"A"<<endl;} }; class B: virtual public A{ void showb(){cout<<"B"<<endl;} class C: virtual public A{ void showc(){cout<<"C"<<endl;} class D: public B, public C{ public: void showd(){cout<<"D"<<endl;} }; void main() { D d; d.showa(); }

25 New class structure of example1
B C D

26 Thinking 1 ? class A{ class C: public A{ public: public:
void showa(){cout<<"A"<<endl; } A(){cout<<"A"<<endl;} }; class B: public A{ void showb(){cout<<"B"<<endl; B(){cout<<"B"<<endl;} class C: public A{ public: void showc(){cout<<"C"<<endl;} C(){cout<<"C"<<endl;} }; class D: public B, public C{ void showd(){cout<<"D"<<endl;} D(){cout<<"D"<<endl;} }; void main() { D d; }

27 Thinking 2? class A{ public: void showa(){cout<<"A"<<endl;
} A(){cout<<"A"<<endl;} }; class B:virtual public A{ void showb(){cout<<"B"<<endl; B(){cout<<"B"<<endl;} class C:virtual public A{ public: void showc(){cout<<"C"<<endl;} C(){cout<<"C"<<endl;} }; class D: public B, public C{ void showd(){cout<<"D"<<endl;} D(){cout<<"D"<<endl;} }; void main() { D d; }

28 Main Contents Virtual base class Rules of assignment in inheritance
Virtual functions Pure virtual functions and Abstract Classes

29 Rules of assignment in inheritance
In case of the following declarations: class B { //…} b; class D: public B {//….}d; We can have the following rules: 1. The object of the base class can be assigned by the object of derived class: b=d;

30 2. The reference of the base class can be initialized by the object of derived class:
B & rb=d; 3. The pointers of the base class can be assigned by the address of the object of derived class: B *pb=&d;

31 Main Contents Virtual base class Rules of assignment in inheritance
Virtual functions Pure virtual functions and Abstract Classes

32 Virtual functions Purpose of polymorphism
Can access different implementations of a function with the same function name. Design and implement systems that are more easily extensible. For example: overloaded functions, operator overloading, etc.

33 Virtual functions (cont.)
For a class, if we have: class Shape{ public: void Draw(); //…}*ShapePtr,ShapeObject; We can have two polymorphisms: ShapePtr->Draw(); Compiler implements dynamic binding Function determined during execution time ShapeObject.Draw(); Compiler implements static binding Function determined during compile-time

34 Virtual functions (cont.)
virtual functions for inherit Declaration: Add keyword virtual before function prototype in base class virtual type func_name(args); A base-class pointer or reference to a derived class object will call the func_name function If a derived class does not define a virtual function it will automatically inherited from the base class

35 Role of virtual functions
Improve the reuse of the code. Provide the uniform interface of the same actions for the sub-classes. Eliminate the time consuming and error prone.

36 Example 1: #include <iostream.h> class B0 { public:
virtual void display() {cout<<"B0::display()"<<endl;} }; class B1: public B0 { public: void display() { cout<<"B1::display()"<<endl; } class D1: public B0 { cout<<"D1::display()"<<endl; }

37 Result1: B0::display() B1::display( ) D1::display()
void main() { B0 b0, *p; B1 b1; D1 d1; p=&b0; p->display(); p=&b1; p=&d1; } Different case 1: void main() { B0 b0; B1 b1; D1 d1; b0.display(); b1.display(); d1.display(); } Result1: B0::display() B1::display( ) D1::display() Result2: B0::display() B1::display( ) D1::display()

38 With the original main function.
Different case 2: class D1: public B0 { }; With the original main function. Result: B0::display() B1::display( ) B0::display() If a derived class does not define the virtual function, it will use the same definition of the virtual function as the base class.

39 Important notes 1: It cannot be a static member function.
Add a keyword virtual before the function prototype, and cannot be used for the definition outside the class. Can be inherited, all the functions with the same name in the derived class belong to virtual function. Called be the pointer or reference of the base class, and decided by the pointer to the class.

40 Example 2: class Employee { public:
Employee(const string& name, int dept) : family_name(name), department(dept) {} virtual void print() const; private: string first_name, family_name; char middle_initial; int department; // ... };

41 void Employee::print() const
{ cout << family_name << "\t" << department << '\n'; // ... } class Manager : public Employee public: Manager(const string& name, int dept, int lvl) : Employee(name, dept), level(lvl) { } void print() const; private: int level; };

42 Result: Brown 1234 Jack 123456 level 2 void Manager::print() const {
Employee::print(); cout << "level\t" << level << '\n'; } void main() Employee e("Brown", 1234),*p; Manager m("Jack", , 2); p=&e; p->print(); p=&m; Result: Brown Jack level

43 Important notes 2: Virtual functions can not be defined as friend functions . Virtual functions can not be overloaded, they must be defined as the same declarations as in the base class with or without virtual. Constructors can not be virtual functions, but destructors can.

44 Main Contents Virtual base class Rules of assignment in inheritance
Virtual functions Pure virtual functions and Abstract Classes

45 Pure virtual functions and Abstract Class
Abstract classes Sole purpose is to provide a base class for other classes No objects of an abstract base class can be instantiated Too generic to define real objects, i.e. TwoDimensionalShape Can have pointers and references Concrete classes - classes that can instantiate objects Provide specifics to make real objects , i.e. Square, Circle

46 Pure virtual functions and Abstract Class (cont.)
Making abstract class Declare one or more virtual functions as “pure” by initializing the function to zero virtual type func_name(args)= 0; Pure virtual function

47 class Shape { public: virtual void rotate(int) = 0; // pure virtual functions virtual void draw() = 0; // pure virtual functions virtual bool is_closed() = 0; // pure virtual functions // ... }; Shape s; // error: variable of abstract class Shape

48 Example 1: #include <iostream.h> class B0 { public:
virtual void display( )=0; }; class B1: public B0 { void display( ){cout<<"B1::display( )"<<endl;}

49 Result: B1::display() D1::display() class D1: public B0 { public:
void display( ){cout<<"D1::display( )"<<endl;} }; void main() { B0 *p; B1 b1; D1 d1; p=&b1; p->display(); p=&d1; } Result: B1::display() D1::display()

50 Example 2: class Shape{ public:
virtual void printShapeName() const = 0; virtual void print() const = 0; }; class Point : public Shape { Point( int a= 0, int b= 0 ); void setPoint( int, int ); int getX() const { return x; } int getY() const { return y; } void printShapeName() const { cout << "Point: "; } void print() const; private: int x, y;

51 Point::Point( int a, int b ) { setPoint( a, b ); }
void Point::setPoint( int a, int b ) { x=a; y=b; } void Point::print() const { cout << '[' << x << ", " << y << ']'<<endl; } class Circle : public Point { public: Circle( double r = 0.0, int x = 0, int y = 0 ); void setRadius( double ); double getRadius() const; virtual double area() const; void printShapeName() const { cout << "Circle: "; } void print() const; private: double radius; // radius of Circle };

52 Circle::Circle( double r, int a, int b ): Point( a, b )
{ setRadius( r ); } void Circle::setRadius( double r ) { radius = r > 0 ? r : 0; } double Circle::getRadius() const { return radius; } double Circle::area() const { return * radius * radius; } void Circle::print() const Point::print(); cout << "Radius = " << radius<<endl;

53 void main() { Point point( 7, 11 ); Circle circle( 3.5, 22, 8 ); point.printShapeName(); // static binding point.print(); // static binding circle.printShapeName(); // static binding circle.print(); // static binding cout<<"Dynamic binding test"<<endl; Shape *arrayOfShapes[2]; arrayOfShapes[0]=&point; //dynamic binding arrayOfShapes[1]=&circle; //dynamic binding arrayOfShapes[0]->printShapeName(); arrayOfShapes[0]->print(); arrayOfShapes[1]->printShapeName(); arrayOfShapes[1]->print(); }

54 The end!


Download ppt "Lecture 11: Virtual Function and Pure Virtual Function"

Similar presentations


Ads by Google