You are on page 1of 24

First, what is virtual inheritance?

Consider the situation :

Class A{};
Class B:public A{};
Class C:public A{};
Class D: public B, public C{};

When we come across such an inheritance behaviour , what we see is that D is actually
inheriting the members of A Twice , once through B and once through C…to resolve this
ambiguity , what we do is to make the base class virtual…this is done through the
statement

Class B: virtual public A{};


Class C: virtual public A{};

This is virtual inheritance ….that makes sure the join class (class D) inherits members of
virtual class only once …..

When do we use it?


Generally, virtual base classes are most suitable when the classes that derive from the
virtual base, and especially the virtual base itself, are pure abstract classes. This means
the classes above the "join class" (class D, in this case ) have very little if any data.
Note: even if the virtual base itself is a pure abstract class with no member data, you still
probably don't want to remove the virtual inheritance within classes B and C. You can use
fully qualified names to resolve any ambiguities that arise, however the object's address
is somewhat ambiguous (there are still two Base class subobjects in the Join object), so
simple things like trying to find out if two pointers point at the same instance might be
tricky. You have to be careful there.

Special Considerations

Initialization list of most-derived-class's constructor directly invokes the virtual base


class's constructor.

Becuase a virtual base class subobject occurs only once in an instance, there are special
rules to make sure the virtual base class's constructor and destructor get called exactly
once per instance. The C++ rules say that virtual base classes are constructed before all
non-virtual base classes. The thing you as a programmer need to know is this:
constructors for virtual base classes anywhere in your class's inheritance hierarchy are
called by the "most derived" class's constructor.

Practically speaking, this means that when you create a concrete class that has a virtual
base class, you must be prepared to pass whatever parameters are required to call the
virtual base class's constructor. And, of course, if there are several virtual base classes
anywhere in your classes ancestry, you must be prepared to call all their constructors.
This might mean that the most-derived class's constructor needs more parameters than
you might otherwise think.
Something obscure that you might not knowEdit section

There is a very special concept called cross delegation. Check this out:

#include <iostream>

class A { public:
virtual void f() = 0;
virtual void b() = 0;
};
class B : public virtual A { public:
virtual void f();
};
void B::f () { b(); }
class C : public virtual A { public:
virtual void b();

};

void C::b() { std::cout << "Function b() called" << std::endl; }

class D : public B, public C { public:

int myDataField;

};

int main() {

D *p1 = new D;
B *p2 = p1;
A *p3 = p1;

p1->f();
p2->f();
p3->f(); //this call to A::f() will successfully call C::b() even
//though class A does not inherit class C.

The cool stuff: when we call function f() in class B, it ends up calling function b() in class
C , a class that it does not know exists. This concept is known as cross delegation.
What is a "virtual member function"?

From an OO perspective, it is the single most important feature of C++: [6.8], [6.9].

A virtual function allows derived classes to replace the implementation provided by the
base class. The compiler makes sure the replacement is always called whenever the
object in question is actually of the derived class, even if the object is accessed by a base
pointer rather than a derived pointer. This allows algorithms in the base class to be
replaced in the derived class, even if users don't know about the derived class.

The derived class can either fully replace ("override") the base class member function, or
the derived class can partially replace ("augment") the base class member function. The
latter is accomplished by having the derived class member function call the base class
member function, if desired.

How can C++ achieve dynamic binding yet also static typing?

When you have a pointer to an object, the object may actually be of a class that is derived
from the class of the pointer (e.g., a Vehicle* that is actually pointing to a Car object).
Thus there are two types: the (static) type of the pointer (Vehicle, in this case), and the
(dynamic) type of the pointed-to object (Car, in this case).

Static typing means that the legality of a member function invocation is checked at the
earliest possible moment: by the compiler at compile time. The compiler uses the static
type of the pointer to determine whether the member function invocation is legal. If the
type of the pointer can handle the member function, certainly the pointed-to object can
handle it as well. E.g., if Vehicle has a certain member function, certainly Car also has
that member function since Car is a kind-of Vehicle.

Dynamic binding means that the address of the code in a member function invocation is
determined at the last possible moment: based on the dynamic type of the object at run
time. It is called "dynamic binding" because the binding to the code that actually gets
called is accomplished dynamically (at run time). Dynamic binding is a result of virtual
functions.

What's the difference between how virtual and non-virtual member functions are
called?

Non-virtual member functions are resolved statically. That is, the member function is
selected statically (at compile-time) based on the type of the pointer (or reference) to the
object.

In contrast, virtual member functions are resolved dynamically (at run-time). That is, the
member function is selected dynamically (at run-time) based on the type of the object,
not the type of the pointer/reference to that object. This is called "dynamic binding."
Most compilers use some variant of the following technique: if the object has one or
more virtual functions, the compiler puts a hidden pointer in the object called a "virtual-
pointer" or "v-pointer." This v-pointer points to a global table called the "virtual-table" or
"v-table."

The compiler creates a v-table for each class that has at least one virtual function. For
example, if class Circle has virtual functions for draw() and move() and resize(), there
would be exactly one v-table associated with class Circle, even if there were a gazillion
Circle objects, and the v-pointer of each of those Circle objects would point to the Circle
v-table. The v-table itself has pointers to each of the virtual functions in the class. For
example, the Circle v-table would have three pointers: a pointer to Circle::draw(), a
pointer to Circle::move(), and a pointer to Circle::resize().

During a dispatch of a virtual function, the run-time system follows the object's v-pointer
to the class's v-table, then follows the appropriate slot in the v-table to the method code.

The space-cost overhead of the above technique is nominal: an extra pointer per object
(but only for objects that will need to do dynamic binding), plus an extra pointer per
method (but only for virtual methods). The time-cost overhead is also fairly nominal:
compared to a normal function call, a virtual function call requires two extra fetches (one
to get the value of the v-pointer, a second to get the address of the method). None of this
runtime activity happens with non-virtual functions, since the compiler resolves non-
virtual functions exclusively at compile-time based on the type of the pointer.

Note: the above discussion is simplified considerably, since it doesn't account for extra
structural things like multiple inheritance, virtual inheritance, RTTI, etc., nor does it
account for space/speed issues such as page faults, calling a function via a pointer-to-
function, etc. If you want to know about those other things, please ask comp.lang.c++;
PLEASE DO NOT SEND E-MAIL TO ME!

When should my destructor be virtual?

When you may delete a derived object via a base pointer.

virtual functions bind to the code associated with the class of the object, rather than with
the class of the pointer/reference. When you say delete basePtr, and the base class has a
virtual destructor, the destructor that gets invoked is the one associated with the type of
the object *basePtr, rather than the one associated with the type of the pointer. This is
generally A Good Thing.

TECHNO-GEEK WARNING; PUT YOUR PROPELLER HAT ON.


Technically speaking, you need a base class's destructor to be virtual if and only if you
intend to allow someone to invoke an object's destructor via a base class pointer (this is
normally done implicitly via delete), and the object being destructed is of a derived class
that has a non-trivial destructor. A class has a non-trivial destructor if it either has an
explicit destructor, or if it has a member object or a base class that has a non-trivial
destructor (note that this is a recursive definition (e.g., a class has a non-trivial destructor
if it has a member object (which has a base class (which has a member object (which has
a base class (which has an explicit destructor)))))).
END TECHNO-GEEK WARNING; REMOVE YOUR PROPELLER HAT

If you had a hard grokking the previous rule, try this (over)simplified one on for size: A
class should have a virtual destructor unless that class has no virtual functions. Rationale:
if you have any virtual functions at all, you're probably going to be doing "stuff" to
derived objects via a base pointer, and some of the "stuff" you may do may include
invoking a destructor (normally done implicitly via delete). Plus once you've put the first
virtual function into a class, you've already paid all the per-object space cost that you'll
ever pay (one pointer per object; note that this is theoretically compiler-specific; in
practice everyone does it pretty much the same way), so making the destructor virtual
won't generally cost you anything extra.

What is a "virtual constructor"?

An idiom that allows you to do something that C++ doesn't directly support.

You can get the effect of a virtual constructor by a virtual clone() member function (for
copy constructing), or a virtual create() member function (for the default constructor).

class Shape {
public:
virtual ~Shape() { } // A virtual destructor
virtual void draw() = 0; // A pure virtual function
virtual void move() = 0;
// ...
virtual Shape* clone() const = 0; // Uses the copy constructor
virtual Shape* create() const = 0; // Uses the default constructor
};

class Circle : public Shape {


public:
Circle* clone() const { return new Circle(*this); }
Circle* create() const { return new Circle(); }
// ...
};

In the clone() member function, the new Circle(*this) code calls Circle's copy constructor
to copy the state of this into the newly created Circle object. In the create() member
function, the new Circle() code calls Circle's default constructor.

Users use these as if they were "virtual constructors":

void userCode(Shape& s)
{
Shape* s2 = s.clone();
Shape* s3 = s.create();
// ...
delete s2; // You probably need a virtual destructor here
delete s3;
}

This function will work correctly regardless of whether the Shape is a Circle, Square, or
some other kind-of Shape that doesn't even exist yet.

Virtual Destructor :

Ask any programmer, he'll immediately reply saying "A destructor is a member function
of a class, which gets called when the object goes out of scope". This means all clean ups
and final steps of class destruction are to be done in destructor. A virtual function is
something which helps a derived class in overriding the implementation of a functionality
of a base class.

The order of execution of destructor in an inherited class during a clean up is like this.
1. Derived class destructor
2. Base class destructor

A difference between a destructor (of course also the constructor) and other member
functions is that, if a regular member function has a body at the derived class, only the
version at Derived class gets executed. Whereas in case of destructors, both derived as
well as base class versions get executed.

Now turning our attention to why a destructor has to be virtual, the reason is that we,
programmers are very smart. We'll do days and nights of work to inherit and extend the
functionality of an existing class which is being used, and say that we don't want to
change the implementation/interface just for the sake of a new entrant. Let me explain
this with an example.
#include <iostream.h>
class Base
{
public:
Base(){ cout<<"Constructor: Base"<<endl;}
~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;}
> };
void main()
{
Base *Var = new Derived();
delete Var;
}

Try executing this code, you'll see the difference. To our observation, the constructors are
getting called in the proper order. But to the dread of a programmer of a large project, the
destructor of the derived class was not called at all.

This is where the virtual mechanism comes into our rescue. By making the Base class
Destructor virtual, both the destructors will be called in order. The following is the
corrected sample.

#include <iostream.h>
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;}
};
void main()
{
Base *Var = new Derived();
delete Var;
}

Note:
There is one more point to be noted regarding virtual destructor. We can't declare pure
virtual destructor. Even if a virtual destructor is declared as pure, it will have to
implement an empty body (at least) for the destructor

Pure virtual destructors :

1) Is the following declaration legal?


class X {
...
public:
X();
virtual ~X() = 0;
};

RESPONSE: rmartin@rcmcon.com (Robert Martin), 17 May 95

Pure virtual destructors are an interesting aspect of C++. If a


function is pure virtual, then the class that contains it is abstract,
and C++ will not allow it to be instantiated.

Purity is inherited. Thus:

struct B {virtual void f() = 0;};


struct D : B {}; // abstract class, pure virtual f is inherited.

However, destructors are *not* inherited. Thus:

struct B {virtual ~B() = 0;};


struct D : B {} // concrete class. Compiler generates destructor.

All classes must have a destructor. If one is not specified, then the
compiler will write one for you. If your destructor is pure virtual,
you still have to supply an implementation.

Thus:

struct B {virtual ~B() = 0;}


B::~B() {/* do whatever */}

If you don't implement the pure virtual destructor, you will get a
link error.

-------------------------------------

What all this adds up to is this. A pure virtual destructor is


exactly like a regular virtual destructor, except that it makes the
class it is declared in, abstract. It does not affect derived classes
at all. In particular, it does not make it a compiler error to omit
destructor declarations from derived classes.

Thus, I use pure virtual destructors as a way of making a class


abstract, if that class has no other pure virtual functions.
Pass by Reference in C

When reading setjmp.h I figured out a nice trick used by glibc hackers to implement pass-
by-reference'd data types. It was like Wow! Cool! Beautiful! Automatic memory
allocation with no reference operator when passing to functions. This has been indeed
part of the design of C and exactly why array types were added to C, yet I never figured
out arrays can be used to implement opaque types that are passed by reference.

#include <stdio.h>

typedef struct __dummy_tag {


int x;
} the_type[1];

void setter(the_type i, int v)


{
i->x = v;
}
int getter(the_type i)
{
return i->x;
}
int main(void)
{
the_type v;
setter (v, 10);
printf ("%d\n", getter (v));
setter (v, 20);
printf ("%d\n", getter (v));
return 0;
}

Why Cast?

Casts are used to convert the type of an object, expression, function argument, or return
value to that of another type. Some conversions are performed automatically by the
compiler without intervention by the programmer. These conversions are called implicit
conversions. The standard C++ conversions and user-defined conversions are performed
implicitly by the compiler where needed. Other conversions which must be explicitly
specified by the programmer and are appropriately called explicit conversions.

Standard conversions are used for integral promotions (e.g., enum to int), integral
conversions (e.g., int to unsigned int), floating point conversions (e.g., float to double),
floating-integral conversions (e.g., int to float), arithmetic conversions (e.g., converting
operands to the type of the widest operand before evaluation), pointer conversions (e.g.,
derived class pointer to base class pointer), reference conversions (e.g., derived class
reference to base class reference), and pointer-to-member conversions (e.g., from pointer
to member of a base class to pointer to member of a derived class).

You can provide a user-defined conversion from a class X to a class Y by providing a


constructor for Y that takes an X as an argument: Y(const X& x) or by providing a class
Y with a conversion operator:

operator X()
When a type is needed for an expression that cannot be obtained through an implicit
conversion or when more than one standard conversion creates an ambiguous situation,
the programmer must explicitly specify the target type of the conversion.

In C, an expression, expr, of type S can be cast to another type T in one of the following
ways. By using an explicit cast:

(T) expr
or by using a functional form:

T(expr)
We will refer to either of these constructs as the old C-style casts.

The old C-style casts have several shortcomings. First, the syntax is the same for every
casting operation. This means it is impossible for the compiler (or users) to tell the
intended purpose of the cast. Is it a cast from a base class pointer to a derived class
pointer? Does the cast remove the ``const-ness'' of the object? Or, is it a conversion of
one type to a completely unrelated type? The truth is, it is impossible to tell from the
syntax. As a result, this makes the cast harder to comprehend, not only by humans, but
also by compilers which are unable to detect improper casts.

Another problem is that the C-style casts are hard to find. Parentheses with an identifier
between them are used all over C++ programs. There is no easy way to ``grep'' a source
file and get a list of all the casts being performed.

Perhaps the most serious problem with the old C-style cast is that it allows you to cast
practically any type to any other type. Improper use of casts can lead to disastrous results.
The old C-style casts have created a few holes in the C type system and have also been a
souce of confusion for both programmers and compilers. Even in C++, the old C-style
casts are retained for backwards compatibility. However, using the new C++ style casting
operators will make your programs more readable, less error-prone and type-safe, and
easier to maintain.

The New C++ Casting Operators

The new C++ casting operators are intended to provide a solution to the shortcomings of
the old C-style casts by providing:
Improved syntax. Casts have a clear, concise, although somewhat cumbersome syntax.
This makes casts easier to understand, find, and maintain.
Improved semantics. The intended meaning of a cast is no longer ambiguous. Knowing
what the programmer intended the cast to do makes it possible for compilers to detect
improper casting operations.
Type-safe conversions. Allow some casts to be performed safely at run-time. This will
enable programmers to check whether a particular cast is successful or not.
C++ introduces four new casting operators:
static_cast, to convert one type to another type;
const_cast, to cast away the ``const-ness'' or ``volatile-ness'' of a type;
dynamic_cast, for safe navigation of an inheritance hierarchy; and
reinterpret_cast, to perform type conversions on un-related types.
All of the casting operators have the same syntax and are used in a manner similar to
templates. For example, to perform a static_cast of ptr to a type T we write:

T* t = static_cast<T> (ptr);
As we will soon see, static_cast is the most general and is intended as a replacement for
most C-style casts. The other three forms are for specific circumstances to be discussed
below.

The static_cast Operator

The static_cast operator takes the form

static_cast<T> (expr)
to convert the expression expr to type T. Such conversions rely on static (compile-time)
type information.

Subject to certain restrictions, you may use static_cast to convert a base class pointer to a
derived class pointer, perform arithmetic conversions, convert an int to an enum, convert
a reference of type X& to another reference of type Y&, convert an object of type X to an
object of type Y, and convert a pointer-to-member to another pointer-to-member within
the same class hierarchy.

Internally, static_casts are used by the compiler to perform implicit type conversions such
as the standard conversions and user-defined conversions. In general, a complete type can
be converted to another type so long as some conversion sequence is provided by the
language.

The downcast of a base class pointer X* to a derived class pointer Y* can be done
statically only if the conversion is unambiguous and X is not a file base class. Consider
this class hierarchy:

class BankAcct
{ /* ... */ }
class SavingsAcct : public BankAcct
{ /* ... */ }
Given a base class pointer, we can cast it to a derived class pointer:

void f (BankAcct* acct)


{
SavingsAcct* d1 =
static_cast<SavingsAcct*>(acct);
}
This is called a downcast. The static_cast operator allows you to perform safe downcasts
for non-polymorphic classes.

Note that static_cast relies on static (compile-time) type information and does not
perform any run-time type checking. This means that if acct does, in fact, not refer to an
actual SavingsAcct the result of the cast is undefined. Borland C++ 4.5, seemingly
incorrectly, still performs the conversion, however, your compiler mileage may vary. If
you want to use run-time type information during conversion of polymorphic class types,
use dynamic_cast. It is not possible to perform a downcast from a file base class using a
static_cast; you must use a dynamic_cast.

More generally a static_cast may be used to perform the explicit inverse of the implicit
standard conversions. A conversion from type S to T can only be done if the conversion
from type T to S is an implicit conversion. Also, the the ``const-ness'' of the original type,
S, must be preserved. You cannot use static_cast to change ``const-ness''; use const_cast
instead.

One of the more common uses of static_cast is to perform arithmetic conversions, such as
from int to double. For example, to avoid the truncation in the following computation:

int total = 500;


int days = 9;
double rate = total/days;
We can write:

double rate =
static_cast<double>(total)/days;

A static_cast may also be used to convert an integral type to an enumeration. Consider:

enum fruit {apple=0,orange,banana};


int i 1 = 2;
fruit f1 = static_cast<fruit> (i1);
The conversion results in an enumeration with the same value as the integral type
provided the integral value is within the range of the enumeration. The conversion of an
integral value that is not within the range of the enumeration is undefined.
You may also use static_cast to convert any expression to a void in which case the value
of the expression is discarded.

One interesting side effect of the old C-style casts, was to gain access to a private base
class of a derived class. Consider this hierarchy:

class Base
{
public:
Base() : _data(999) {}
int Data() const {return _data;}
private:
int _data;
};

class Derived : private Base


{
public:
Derived () : Base() {}
};

Derived* d1 = new Derived;


Normally, you should not be able to access Data() through the pointer d1. However, using
an old C-style cast, we can:

Base* b1 = (Base*) d1;


int i = b1->Data(); // works!
The good news is that if you attempt to use static_cast:

Base* b1 = static_cast<Base*>(d1);
the compiler will correctly report that Base is inaccessible because it is a private base
class.

Another unfortunate hole created in the type system by the old C-style casts results with
incomplete types. Consider:

class X; // incomplete
class Y; // incomplete
The old C-style casts, let us cast from one incomplete type to another! Here is an
example:

void f(X* x)
{
Y* y = (Y*) x; // works!
}
Thankfully, this hole has also been plugged by static_cast:
void f(X* x)
{
Y* y = static_cast<Y*> x; // fails
}

The const_cast Operator

The const_cast operator takes the form

const_cast<T> (expr)
and is used to add or remove the ``const-ness'' or ``volatile-ness'' from a type.

Consider a function, f, which takes a non-const argument:

double f( double& d );
However, we wish to call f from another function g:

void g (const double& d)


{
val = f(d);
}
Since d, which is const and should not be modified, the compiler will complain because f
may potentially modify its value. To get around this dilemma, we can use a const_cast:

void g (const double& d)


{
val = f(const_cast<double&>(d));
}
which strips away the ``const-ness'' of d before passing it to f.

Another scenario where const_cast is useful is inside const functions. Remember that
when you make a member function const, you are telling your users (and the compiler)
that calling this function will not change the value of the object. However, in some cases,
we find that it is sometimes still necessary to change the value of some internal data
members inside a function that is const. For example, consider class B:

class B
{
public:
B() {}
~B() {}
void f() const;
private:
int _count;
};
Suppose that, f(), which is declared to be const, must modify _count whenever it is
called:

void B::f() const


{
_count += 1;
}
The compiler will not allow _count to be changed because the function is const. Just how
does the compiler perform this magic? Turns out that the type of the internal this pointer
helps the compiler perform this check.

Every non-static member function of a class C has a this pointer. For non const member
functions of class C, this has type

C * const
This means that this is a constant pointer. In other words, you cannot change what the
pointer this points to, after all, that would be disastrous, wouldn't it? However, you can
still change what ever this points to (i.e., you can change data members of class C).

For const member functions of class C, this has a type of

const C * const
Not only is this a constant pointer but also what is pointed to is constant. So the data
members of C may not be changed through the this pointer. This is how the compiler
ensures that you do not modify data members inside const functions.

Examining the member function B::f again, the statement _count is actually interpreted as
this->_count. But since this has type const B * const, it cannot be used to change the
value of _count so the compiler reports an error.

We can, however, use const_cast to cast away the ``const-ness'' of this:

void B::f() const


{
B* const localThis =
const_cast<B* const>(this);
localThis->_count += 1;
}

Actually, you should not be casting away the ``const-ness'' of this using const_cast. C++
now has the keyword mutable for those data members whose value may be changed by
const functions. By declaring _count as:

mutable int _count;


We can use the original implementation of B::f without casting away the ``const-ness'' of
this.
const_cast can also be used to strip away the ``volatile-ness'' of an object in a similar
manner. You cannot use const_cast for any other types of casts, such as casting a base
class pointer to a derived class pointer. If you do so the compiler will report an error.

The dynamic_cast Operator

The dynamic_cast operator takes the form

dynamic_cast<T> (expr)
and can be used only for pointer or reference types to navigate a class hierarchy. The
dynamic_cast operator can be used to cast from a derived class pointer to a base class
pointer, cast a derived class pointer to another derived (sibling) class pointer, or cast a
base class pointer to a derived class pointer. Each of these conversions may also be
applied to references. In addition, any pointer may also be cast to a void*.

The dynamic_cast operator is actually part of C++'s run-time type information or RTTI
sub-system. As such, it has been provided for use with polymorphic classes - those
classes which have at least one file function. Use static_cast to perform conversions
between non-polymorphic classes.

All of the derived to base conversions are performed using the static (compile-time) type
information. These conversions may, therefore, be performed on both non-polymorphic
and polymorphic types. These conversions will produce the same result if they are
converted using a static_cast. These conversions are fairly straightforward so we won't
discuss them further.

Conversions down the hierarchy from base to derived or across a class hierarchy rely on
run-time type information and can only be performed on polymorphic types. Such
conversions can now be performed safely since dynamic_cast will indicate whether the
conversion is successful. When performing a dynamic_cast on a pointer, a null pointer is
returned when the cast is unsuccessful. When a reference is being cast, a Bad_cast
exception is thrown.

Let's look at the power of run-time type conversions by revisiting the bank account
hierarchy introduced above with static_cast. Recall that when acct does not actually point
to a SavingsAcct object the result of the static_cast is undefined. Since BankAcct has at
least one file function it is a polymorphic class. We can use a dynamic_cast instead to
check that the cast was successful:

void f (BankAcct* acct)


{
SavingsAcct* d1 =
dynamic_cast<SavingsAcct*>(acct);
if (d1)
{
// d1 is a savings account
}
}

Let's expand our bank account hierarchy to include a few more types of accounts, such as
a checking account and a money market account. Let's suppose we also want to extend
the functionality so that we can credit the interest for all savings and money market
accounts in our database. Suppose further that BankAcct is part of a vendor library; we
are not able to add any new members functions to BankAcct since we do not have the
source code.

Clearly, the best way to incorporate the needed functionality would be to add a file
function, creditInterest() to the base class, BankAcct. But since we are not able to modify
BankAcct we are unable to do this. Instead, we can employ a dynamic_cast to help us.

We add the method creditInterest() to both SavingsAcct and MMAcct classes. The
resulting class hierarchy looks like:

class BankAcct { /* ... */ }


class SavingsAcct : public BankAcct
{
public:
// ...
void computeInterest();
}
class MMAcct : public BankAcct
{
public:
// ...
void computeInterest();
}
We can now compute interest for an array of BankAcct*s:

void DoInterest (BankAcct* a[],


int num_accts)
{
for (int i = 0; i < num_accts; i++)
{
// Check for savings
SavingsAcct* sa =
dynamic_cast<SavingsAcct*>(accts[i]);
if (sa)
{
sa->creditInterest();
}
MMAcct* mm =
dynamic_cast<MMAcct*>(accts[i]);
if (mm)
{
mm->creditInterest();
}
}
}
A dynamic_cast will return a null pointer if the cast is not successful. So only if the
pointer is of type SavingsAcct* or MMAcct* is interest credited. dynamic_cast allows
you to perform safe type conversions and let's your programs take appropriate actions
when such casts fail.

When a pointer is converted to a void*, the resulting object points to the most derived
object in the class hierarchy. This enables the object to be seen as raw memory. Meyers
[3] demonstrates how a cast to void* can be used to determine if a particular object is on
the heap.

The reinterpret_cast Operator

The reinterpret_cast operator takes the form

reinterpret_cast<T> (expr)
and is used to perform conversions between two unrelated types. The result of the
conversion is usually implementation dependent and, therefore, not likely to be portable.
You should use this type of cast only when absolutely necessary.

A reinterpret_cast can also be used to convert a pointer to an integral type. If the integral
type is then converted back to the same pointer type, the result will be the same value as
the original pointer.

Meyers [3] shows how reinterpret_casts can be used to cast between function pointer
types.

Summary

The new C++ cast operators enable you to develop programs which are easier to
maintain, understand, and perform some conversions safely. Casts should not be taken
lightly. As you convert your old C-style casts to use the new C++ casting operators ask
yourself if a cast is really needed here. It may be that you are using a class hierarchy in a
way not originally intended or that you may be able to do the same thing with file
functions.

Difference Between new and malloc:

Answer
both malloc and new functions are used for dynamic memory allocations and the basic
difference is: malloc requires a special "typecasting" when it allocates memory for eg. if
the pointer used is the char pointer then after the processor allocates memory then this
allocated memory needs to be typecasted to char pointer i.e (char*).but new does not
requires any typecasting. Also, free is the keyword used to free the memory while using
malloc and delete the keyword to free memory while using new, otherwise this will lead
the memory leak.

Answer

Besides the basic syntactical difference: malloc is a C function which will allocate the
amount of memory you ask and thats it. new is a C++ operator which will allocate
memory AND call the constructor of the class for which's object memory is being
allocated.

Similarily, free is a C function which will free up the memory allocated. but delete is a
C++ operator which will free up the allocated memory AND call the destructor of the
object.

Introduction

One of the most common questions that get asked during interviews for C++
programmers is to explain the differences between using malloc and using new. It's also a
fairly common question in some of newsgroups and C++ forums. This article will try and
explain as simply as possible how malloc and new are two entities that are essentially
non-interchangeable, and there is nothing is this article that you wouldn't find in most
decent C++ programming books; but the article tries to put all the information together in
a single place using simple code snippets and is targeted at newbies who might be
unfamiliar as to the differences.

Constructors and Destructors

When you new an object, space for the object is not only allocated but the object's
constructor is called. And similarly when you delete an object, the object's destructor is
called before the memory is released. If you use malloc and free, the destructor and
constructor do not get called respectively and obviously, this simply won't do in C++
except in certain very rare situations where you have classes without any specific
destructor/constructors.

It's very easy to test this out by using the following test class.

class Test
{
public:
Test()
{
cout << "Test : ctor\r\n";
}
~Test()
{
cout << "Test : dtor\r\n";
}
void Hello()
{
cout << "Test : Hello World\r\n";
}
};

Create, use and delete the object using new/delete as well as using malloc/free :-

int _tmain(int argc, _TCHAR* argv[])


{
cout << "1\r\n";
Test* t1 = new Test();
t1->Hello();
delete t1;

cout << "2\r\n";


Test* t2 = (Test*) malloc(sizeof Test);
t2->Hello();
free(t2);

return 0;
}

You'll see the following output:-

1
Test : ctor
Test : Hello World
Test : dtor
2
Test : Hello World

As obvious from the output, malloc/free did not result in either the destructor or the
constructor being called.
Choosing constructor overloads

For non-array allocations, you can actually specify the specific overload of the
constructor that you wish to use as in :- T t = new T(x, y, z); For array allocations using
new, the default constructor will get used. If you attempt an array allocation on an object
that does not have a default constructor, you get a compiler error :-

class Test2
{
public:
Test2(int y)
{
}
};

//...

Test2* t2array = new Test2[10];

For example, if you attempt to compile the above snippet, you'll get an error C2512:
'Test2' : no appropriate default constructor available with the VC++ 7.1 compiler.
Type-casting forced by malloc

Because malloc returns a void* the caller has to do a type-cast to get it to compile.

Test* t1 = new Test();

is so much easier to code and is a lot more readable than

Test* t2 = (Test*) malloc(sizeof Test);

Native types

For native types new/delete and malloc/free work the same way except for the need to
type-cast in the case of malloc/free. So it's just a matter of user preference.

//declaring native type

int* i1 = new int;


delete i1;

int* i2 = (int*) malloc(sizeof(int));


free(i2);

//declaring native type array

char** c1 = new char*[10];


delete[] c1;

char** c2 = (char**) malloc(sizeof(char)*10);


free(c2);

Safety tip
Always delete what you new, and free what you malloc, never mix new with free or
malloc with delete.

The reason for this is that if you do that, then the behavior is technically undefined
because there is no guarantee that new would internally use malloc, or that delete would
internally use free.

Tip for scalar and vector new/delete

Thanks to Mike Dunn for referring me to Raymond Chen's blog on this issue. The basic
point is that you should not mix scalar new with vector delete and vice versa.

Test* t = new Test[3];


delete t; // <-- This is very bad

The above code will result in a memory leak as only the first Test object is deleted.

Test* t = new Test;


delete[] t; // <-- This is even worse

Similarly, the above code snippet is just as bad and probably worse by a good deal. The
vector delete will try to delete more objects depending on the random value it gets from
its object-count location and will obviously result in heap corruption.

No realloc alternative for new/delete

The new/delete couple not have a realloc alternative that is available when you use the
malloc/free pair. realloc is pretty handy if you want to resize the length of an array or a
memory block dynamically, specially since the contents of the array/block remain same
up to the shorter of the old and new sizes. To see this in action, see the following code
snippet :-

char* p = (char*)malloc(sizeof(char)*12);
strcpy(p,"hello world");
cout << p << "\r\n";
p = (char*)realloc(p, sizeof(char)*24);
strcat(p," from Nish");
cout << p << "\r\n";
free(p);

The output you get will be :-

hello world
hello world from Nish

As you can see from the output, the original contents were retained. Thanks to Minox for
reminding me of the realloc issue.

Memory Leaks

When a class uses dynamically allocated memory internally, all sorts of issues arise. If
not properly handled, they can lead to memory leaks and corrupt data structures.

A memory leak is the situation that occurs when dynamically allocated memory is lost to
the program. For example:

char * p;

p = new char[10000];

...

p = new char[5000];

10000 bytes are dyanmically allocated and the address of those bytes is stored in p. Later
on 5000 bytes are dynamically allocated and the address is stored in p. However, the
original 10000 bytes have not been returned to the system using the delete [] operator.
The program has essentially forgotten where these bytes are located.

The result of a memory leak depends on the nature of the program and the operating
system it runs on. In a program that is designed to run for long periods of time (like a web
server) memory leaks can eat away at the system resources until the point when the
program requires more memory, none is available to be allocated. The program will not
function properly and most likely crash.

In most modern operating systems all of the memory used by a program (leaked or
otherwise) is recovered when the program terminates. In some operating systems
however, the memory is lost until the machine is rebooted.

Preventing memory leaks is the responsibility of the programmer. To some people, this is
so odious that they have created systems for automatically recovering dynamically
allocated memory that is no longer being used. This is one of the features of the Java
programming language. This feature, known as automatic garbage collection, has its own
problems, but that's a discussion for another time.

What is the diff between SendMessage & Postmessage?

SendMessage gets called immediately and (usually) completes before


returning. Its more like a function call.

PostMessage is put on a queue and gets executed afterwards (usually some


time after the current message handler has finished processing the current
message)

You might also like