Saturday, May 2, 2015

1. Polymorphism
 Đa hình là cách mà implement một function member trong base class, cách mà function member đó được redefine trong derived class như thế nào. Đa hình liên quan đến các khái niện inheritance, virtual function

Ex
polymorphism.cpp

 #include <iostream>   
 using namespace std;  
    
 class Shape {  
   protected:  
    int width, height;  
   public:  
    Shape( int a=0, int b=0)  
    {  
      width = a;  
      height = b;  
    }  
      
    int area()  
    {  
      cout << "Parent class area :" <<endl;  
      return 0;  
    }  
 };  
   
 class Rectangle: public Shape{  
   public:  
    Rectangle( int a=0, int b=0):Shape(a, b) { }  
    int area ()  
    {   
      cout << "Rectangle class area :" <<endl;  
      return (width * height);   
    }  
 };  
   
 class Triangle: public Shape{  
   public:  
    Triangle( int a=0, int b=0):Shape(a, b) { }  
    int area ()  
    {   
      cout << "Triangle class area :" <<endl;  
      return (width * height / 2);   
    }  
 };  
   
 // Main function for the program  
 int main( )  
 {  
   Shape *ps;  
     
   Shape shape(10, 11);  
   Rectangle rec(10,7);  
   Triangle tri(10,5);  
   
   // store the address of Shape  
   ps = &shape;  
   // call shape area.  
   ps->area();  
     
   // store the address of Rectangle  
   ps = &rec;  
   // call rectangle area.  
   ps->area();  
   
   // store the address of Triangle  
   ps = &tri;  
   // call triangle area.  
   ps->area();  
     
   return 0;  
 }  
   



Compile & Execute:
 $ g++ polymorphism.cpp   
 $ ./a.out   
 Parent class area :  
 Parent class area :  
 Parent class area :  
   

Khi chạy thấy print kết quả ra sai, đáng lý ra kết quả đúng phải là Parent-Rectange -Triangle mới đúng, lý do sai là vì compiler sẽ thực hiện biên dịch một lần duy nhất khi gặp hàm area( ) trong base class, các hàm area( ) khác trong derived class bị bỏ qua.
Để khắc phục điều này thì cần khai báo thêm từ khóa virtual trước hàm area( ), chính điều này tạo ra tính đa hình trong C++


 class Shape {  
   protected:  
    int width, height;  
   public:  
    Shape( int a=0, int b=0)  
    {  
      width = a;  
      height = b;  
    }  
    virtual int area()  
    {  
      cout << "Parent class area :" <<endl;  
      return 0;  
    }  
 };  

Compile & Execute:
 $ g++ polymorphism.cpp   
 $ ./a.out 
 Parent class area :  
 Rectangle class area :  
 Triangle class area :  
   

2. Virtual function
Hàm ảo là hàm được khai báo và implement trong base class sử dụng với từ khóa virtual, và hàm này được re-implement lại trong derived class. Như ví dụ trên thì hàm
virtual int area( ) chính là một hàm ảo.

3. Pure virtual function
Hàm thuần ảo cũng được khai báo với từ khóa virtual nhưng nó lại không được implement trong base class, điều đó dẫn đến nó bắt buộc phải được implement trong derived class.

Ex
 class Shape {  
   protected:  
    int width, height;  
   public:  
    Shape( int a=0, int b=0)  
    {  
      width = a;  
      height = b;  
    }  
    // pure virtual function  
    virtual int area() = 0;  
 };  

Note: Một hệ quả là không thể tạo ra object từ base class.

Xét vd trên khi compile đến đoạn khai báo 
 Shape shape(10, 11);  
 thì sẽ bị lỗi.

Ex
pure-virtual-function.cpp
 #include <iostream>   
 using namespace std;  
    
 class Shape {  
   protected:  
    int width, height;  
   public:  
    Shape( int a=0, int b=0)  
    {  
      width = a;  
      height = b;  
    }  
   
    virtual int area() = 0;  
 };  
   
 class Rectangle: public Shape{  
   public:  
    Rectangle( int a=0, int b=0):Shape(a, b) { }  
    int area ()  
    {   
      cout << "Rectangle class area :" <<endl;  
      return (width * height);   
    }  
 };  
   
 class Triangle: public Shape{  
   public:  
    Triangle( int a=0, int b=0):Shape(a, b) { }  
    int area ()  
    {   
      cout << "Triangle class area :" <<endl;  
      return (width * height / 2);   
    }  
 };  
   
 // Main function for the program  
 int main( )  
 {  
   
   Shape *ps;  
   
   Rectangle rec(10,7);  
   Triangle tri(10,5);  
   
   // store the address of Rectangle  
   ps = &rec;  
   // call rectangle area.  
   ps->area();  
   
   // store the address of Triangle  
   ps = &tri;  
   // call triangle area.  
   ps->area();  
   
   return 0;  
 }  
   

Compile & Execute
 $ g++ pure-virtual-function.cpp   
 $ ./a.out   
 Rectangle class area :  
 Triangle class area :  
   

4. Virtual Destructor
Hàm hủy ảo là một destructor được khai báo dạng virtual function, có tác dụng đảm bảo cho việc thực hiện hàm hủy đúng thứ tự khi giải phóng một object thuộc derived class.
+ Khi khởi tạo (new) một object của derived class thì sẽ lần lượt gọi base constructor rồi đến derived constructor
+ Khi giải phóng (delete) một object của derived class thì sẽ lần lượt gọi derived destructor rồi mới đến base destructor 

Ex:
virtual-destructor.cpp
 #include <iostream>  
 using namespace std;  
   
 class Base  
 {  
 public:  
   Base(){  
     cout<<"Constructor: Base"<<endl;  
   }  
   
   virtual ~Base(){  
     cout<<"Destructor : Base"<<endl;  
   }  
 };  
   
 class Derived: public Base  
 {  
   //Doing a lot of jobs by extending the functionality  
 public:  
   Derived(){  
     cout<<"Constructor: Derived"<<endl;  
   }  
   
   ~Derived(){  
     cout<<"Destructor : Derived"<<endl;  
   }  
 };  
   
 int main()  
 {  
   Base *Var = new Derived();  
   delete Var;  
 }  
   

Compile & Execute:
 $ g++ virtual-destructor.cpp   
 $ ./a.out   
 Constructor: Base  
 Constructor: Derived  
 Destructor : Derived  
 Destructor : Base  
   

Thử trong trường hợp không có virtual ở base class sẽ đươc kết quả sai như dưới
 $ g++ virtual-destructor.cpp   
 $ ./a.out   
 Constructor: Base  
 Constructor: Derived  
 Destructor : Base  
   

Note: Vì lý do trên nên tốt nhất là luôn khai báo destructor là virtual destructor ở cả base class lẫn derived class

Leave a Reply

Subscribe to Posts | Subscribe to Comments

- Copyright © Lập trình hệ thống nhúng Linux . Powered by Luong Duy Ninh -