Wednesday, August 29, 2007

Virtual Functions


C++ virtual function is a member function of a class, whose functionality can be over-ridden in its derived classes. The whole function body can be replaced with a new set of implementation in the derived class. The concept of c++ virtual functions is different from C++ Function overloading.

By default, C++ matches a function call with the correct function definition at compile time. This is called static binding. You can specify that the compiler match a function call with the correct function definition at run time; this is called dynamic binding. You declare a function with the keyword virtual if you want the compiler to use dynamic binding for that specific function.
C++ Virtual Function - Properties:
C++ virtual function is,
• A member function of a class
• Declared with virtual keyword
• Usually has a different functionality in the derived class
• A function call is resolved at run-time
The difference between a non-virtual c++ member function and a virtual member function is, the non-virtual member functions are resolved at compile time. This mechanism is called static binding. Where as the c++ virtual member functions are resolved during run-time. This mechanism is known as dynamic binding.
C++ Virtual Function - Reasons:
The most prominent reason why a C++ virtual function will be used is to have a different functionality in the derived class.
For example a Create function in a class Window may have to create a window with white background. But a class called CommandButton derived or inherited from Window, may have to use a gray background and write a caption on the center. The Create function for CommandButton now should have a functionality different from the one at the class called Window.
C++ Virtual function - Example:
This article assumes a base class named Window with a virtual member function named Create. The derived class name will be CommandButton, with our over ridden function Create.
class Window // Base class for C++ virtual function example
{
public:
virtual void Create() // virtual function for C++ virtual function example
{
cout <<"Base class Window"< }
};
class CommandButton : public Window
{
public:
void Create()
{
cout<<"Derived class Command Button - Overridden C++ virtual function"< }
};

void main()
{
Window *x, *y;

x = new Window();
x->Create();

y = new CommandButton();
y->Create();
}

The output of the above program will be,
Base class Window
Derived class Command Button
If the function had not been declared virtual, then the base class function would have been called all the times. Because, the function address would have been statically bound during compile time. But now, as the function is declared virtual it is a candidate for run-time linking and the derived class function is being invoked.
C++ Virtual function - Call Mechanism:
Whenever a program has a C++ virtual function declared, a v-table is constructed for the class. The v-table consists of addresses to the virtual functions for classes and pointers to the functions from each of the objects of the derived class. Whenever there is a function call made to the c++ virtual function, the v-table is used to resolve to the function address. This is how the Dynamic binding happens during a virtual function call.

Therefore, a virtual function is a member function you may redefine for other derived classes, and can ensure that the compiler will call the redefined virtual function for an object of the corresponding derived class, even if you call that function with a pointer or reference to a base class of the object.
A class that declares or inherits a virtual function is called a polymorphic class.


The following restrictions apply to constructors and destructors:
• Constructors and destructors do not have return types nor can they return values.
• References and pointers cannot be used on constructors and destructors because their addresses cannot be taken.
• Constructors cannot be declared with the keyword virtual.
• Constructors and destructors cannot be declared static, const, or volatile.
• Unions cannot contain class objects that have constructors or destructors



________________________________________
Copy Assignment Operators
The copy assignment operator lets you create a new object from an existing one by initialization. A copy assignment operator of a class A is a nonstatic nontemplate member function that has one of the following forms:
• A::operator=(A)
• A::operator=(A&)
• A::operator=(const A&)
• A::operator=(volatile A&)
• A::operator=(const volatile A&)
If you do not declare a copy assignment operator for a class A, the compiler will implicitly declare one for you which will be inline public.
The following example demonstrates implicitly defined and user-defined copy assignment operators:
#include
using namespace std;

struct A {
A& operator=(const A&) {
cout << "A::operator=(const A&)" << endl;
return *this;
}

A& operator=(A&) {
cout << "A::operator=(A&)" << endl;
return *this;
}

};
class B {
A a;
};
struct C {
C& operator=(C&) {
cout << "C::operator=(C&)" << endl;
return *this;
}
C() { }
};

int main() {
B x, y;
x = y;

A w, z;
w = z;

C i;
const C j();
// i = j;
}
The following is the output of the above example:
A::operator=(const A&)
A::operator=(A&)
The assignment x = y calls the implicitly defined copy assignment operator of B, which calls the user-defined copy assignment operator A::operator=(const A&). The assignment w = z calls the user-defined operator A::operator=(A&). The compiler will not allow the assignment i = j because an operator C::operator=(const C&) has not been defined.
The implicitly declared copy assignment operator of a class A will have the form A& A::operator=(const A&) if the following are true:
• A direct or virtual base B of class A has a copy assignment operator whose parameter is of type const B&, const volatile B&, or B.
• A non-static class type data member of type X that belongs to class A has a copy constructor whose parameter is of type const X&, const volatile X&, or X.
If the above are not true for a class A, the compiler will implicitly declare a copy assignment operator with the form A& A::operator=(A&).
The implicitly declared copy assignment operator returns a reference to the operator's argument.
The copy assignment operator of a derived class hides the copy assignment operator of its base class.
The compiler cannot allow a program in which the compiler must implicitly define a copy assignment operator for a class A and one or more of the following are true:
• Class A has a nonstatic data member of a const type or a reference type
• Class A has a nonstatic data member of a type which has an inaccessible copy assignment operator
• Class A is derived from a base class with an inaccessible copy assignment operator.
An implicitly defined copy assignment operator of a class A will first assign the direct base classes of A in the order that they appear in the definition of A. Next, the implicitly defined copy assignment operator will assign the nonstatic data members of A in the order of their declaration in the definition of A.
Related References
• Assignment Expressions

0 comments;Click here for request info on this topic:

Post a Comment