When using dynamic_cast in Visual C++ 6.0

June 27, 2008

Dynamic cast is normally used to cast an object of derived type to the base type when the classes are polymorphic type (they contain virtual functions and method over riding).

#include <assert.h>

class CBase

{

public:

virtual ~CBase();

virtual void MyFunction() { cout<<“Base”; }

};

class CDerived : public CBase

{

public:

~CDerived();

void MyFunction() { cout<<“Derived”; }

};

int main()

{

CBase* Base = new CDerived();

CDerived* Derived = dynamic_cast<CDerived*>(Base);

assert(Derived);

delete Base;

return 0;

}

Although the code is perfectly legal, in VS 6.0, the compiler will throw a warning

“dynamic_cast’ used on polymorphic type ‘class CBase’ with /GR-; unpredictable behavior may result”.

And if you ignore the warning and run the program, you will get an exception thrown at the line of dynamic cast.

This is because the VC++ 6.0 compiler is not using the feature of Runtime type Information (RTTI).
To enable RTTI, go to Project–>Settings–>C/C++ and in the Category combo box, select C++ Language. Now enable the check box “Enable Runtime type Information (RTTI)”.

Now compile the program and run it.

If you call Base->Myunction() and Derived->MyFunction(), you will get result as “Derived” and it is quite expected.

If you try to dynamic cast a base class to derived class, with the above option, the compiler won’t show any warning, but the result will be NULL. (Note the assert statement in the code). So be careful to cast only the right type.

Instead, if you use the following code snippet,

CBase* Base = new CBase();

CDerived* Derived = static_cast<CDerived*>(Base);

assert(Derived);

Base->MyFunction();

Derived->MyFunction();

delete Base;

the code will compile and run successfully. But the result will be “Base” for both calls.

static_cast does not employ any kind of run time type checking.

dynamic_cast has that overhead, but it is safer.

Advertisements

How to invoke a function before main() starts

June 26, 2008

Normally main() is the first function executed in a C++ program. But there may be certain situations where we have to invoke certain functions (like hardware check) before the main() starts.

To achieve this, call the function to be invoked in the constructor of a global object.

For example, see the following code segment.

class CHardwareChecker

{

public:

CHardwareChecker()

{

CheckHardware(); // Function to be invoked before main() starts

………….

}

};

CHardwareChecker HardwareChecker; // Global object

int main()

{

……….

}


How to avoid compiler warning with unused parameters

June 10, 2008

There may be unused formal parameters for a function. This is quite natural in the case of polymorphism, where one of the derived classes may use a parameter which is not at all needed in other derived classes. But you may be forced to pass it (of course, dummy value) in the base class (and in all the derived classes indeed). Now in all the derived classes where the parameter is not at all used, the compiler will pop up with a warning – “unused parameter!!!”.

Although this is harmless, I would avoid the warning in the following way.

void MyClass::MyFunction(bool nonUsedParameter)

{

UNREFERENCED_PARAMETER(nonUsedParameter);

// The code continues

}

A better altenative is to code as follows.

void MyClass::MyFunction(bool /*nonUsedParameter*/)

{

// The code continues

}

Another method is to use the macro UNUSED_ALWAYS, defined in afx.h (Generously informed by Nibu, see comments) instead of UNUSED_PARAMETER.