Tuesday, May 4, 2010

OOP in C++ - contd...

virtual functions: Virtual functions are C++ way to achieve run-time polymorphism. Unlike Java, C++ provides calls derived class's version only if base class's method is declared virtual. If method is not declared virtual in base class C++ will always call base class's version irrespective of the object being pointed to. C++ doesn't have abstract key work but supports the abstract class concept. Function is called pure virtual function that doesn't have body.
Example
class Base {
public:
// Pure virtual function.
virtual void display() = 0;
};

Class with at least one pure virtual function is called abstract class. (Abstract class whose object can't be created.) If derived class doesn't implement pure virtual function method of base class it also remains abstract. C++ achieves runtime polymorphism by creating virtual table for each class (and also all it's sub classes) that has virtual method. Each object of that class contains a pointer called virtual pointer that points to the virtual table. Virtual table contains location of the methods. It stores location of derived class version for virtual methods and location of base class version for non-virtual methods.

Example:
class Base {
public:
virtual void display() {
cout << "In base";
}

void show() {
cout << "In base show";
}

virtual ~Base() {}
};

class Derived : public Base {
public:
void display() {
cout << "In derived" <<>
}
};

int main() {
Base *base = new Derived;
base->display();
base->show();
delete base;
}

Output:
In derived
In base show

Execution sequence: When base.display() is called. Internally it asks *(vptr->display)(). In virtual function compiler instead of using this it uses vptr. vptr points to the class's virtual table, in this case derived class's virtual table. When virtual table is constructed address of base class version is inserted for all non-virtual methods. That's why late binding works only for virtual methods and only with pointers.

virtual destructor: As with normal virtual function we want destructor of class being pointed to be called rather than base class's destructor when we delete the object. If destructor is not declared virtual compiler will call base class's destructor which will result in invalid deletion of the object. Hence every time we have virtual method in a class, class's destructor should also be declared virtual.

virtual base class: Not seen usage of this feature but for the sake of completeness. C++ has another feature called virtual base class inheritance. In one particular case of multiple inheritance there can be a conflict in accessing data.
Example:
class Base {
protected:
int data;
};

class Derived1 : public Base {
};

class Derived2 : public Base {
};

class Derived3 : public Derived1, public Derived2 {
public:
void display() {
cout <<>
}
};

See class Derived3. In above case compiler will find conflict in deciding which derived class's data it should refer to. Conflict can resolved by using Derived2::data or Derived3::data. There is one more way. If we want both derived classes to share base class's data we can inherit them virtually.

class Derived1 : virtual public Base {
};

class Derived2 : virtual public Base {
};

In this case Derived1 and Derived2 will share the same data.

No comments:

Post a Comment