Hi guys and Gals,
Have some trouble digesting some facts about Casting in C++.

1). Why can't we use a static_cast for safe downcasting on a polymorphic class?

2).Consider this snippet..

class A {};
class B { public: B (A a) {} };
A a;
B b=a;

How does this implicit typecast seem to work.?
Can you throw some light on this.

Thanks in advance..

Recommended Answers

All 8 Replies

a constructor which a. can be called with one arg b. is not marked explicit is also an implicit conversion operator.

struct A{}; struct C {};
struct B 
{ 
   B(const A&) {} 
   explicit B(const C& ) {}
};
A a ; C c ;
B b = a ; // ok, equiv to B b( B(a) ) ;
// B b2 = c ; // error, no implicit conversion from C to B
B b3 = B(c) ; // ok, conversion is explicit

Hi guys and Gals,
Have some trouble digesting some facts about Casting in C++.

1). Why can't we use a static_cast for safe downcasting on a polymorphic class?

2).Consider this snippet..

class A {};
class B { public: B (A a) {} };
A a;
B b=a;

How does this implicit typecast seem to work.?
Can you throw some light on this.

Thanks in advance..

1. Because that work is done by dynamic_cast. That is not what static_cast is made to do.
Here is what cplusplus.com has to say which I think answers this satisfactorily: static_cast can perform conversions between pointers to related classes, not only from the derived class to its base, but also from a base class to its derived. It ensures that at least the classes are compatible if the proper object is converted, but no safety check is performed during runtime to check if the object being converted is in fact a full object of the destination type. Therefore, it is up to the programmer to ensure that the conversion is safe. On the other side, the overhead of the type-safety checks of dynamic_cast is avoided.
2. Answered by Vijayan.

See http://www.cplusplus.com/doc/tutorial/typecasting.html, should clarify most doubts.

I checked that one out but what baffles me is the reasoning that is missing.

Although yes, the dynamic_cast is supposed to handle that like you rightly pointed out but can anyone tell me why??
That is .. internally what prohibits the compiler to safely typecast an instance of a class with a virtual function ?

An example would greatly help.

>1). Why can't we use a static_cast for safe downcasting on a polymorphic class?
Because static_cast isn't always safe for downcasting. That's why dynamic_cast exists: to perform a runtime check that the cast is legitimate and behave predictably if it's not.

>How does this implicit typecast seem to work.?
There's no implicit typecast. You're calling the constructor for B, which takes an argument of type A. This is syntactic sugar for non-explicit constructors.

>Because static_cast isn't always safe for downcasting. That's why dynamic_cast exists: to perform a runtime check that the cast is legitimate and behave predictably if it's not.

I believe then, that this iilegitimate casting can be performed with C style casting without the compiler cribbing about it.

>I believe then, that this iilegitimate casting can be performed with C style
>casting without the compiler cribbing about it.
No, a C-style cast is just as unsafe as static_cast for downcasting. If the cast can't be performed, you have undefined behavior. With a dynamic_cast, you get a null pointer and no undefined behavior. That's a rather huge difference in safety, no?

>> That is .. internally what prohibits the compiler to safely typecast an instance of a class with a virtual function ?
compiler can't take that decision because you donno what will be the real type of obj you get at runtime while you're compiling. Consider following assuming D1 and D2 derive from B, it'll compile but won't run not as expected at least :).

void foo( B* pb )
{
     D1* pd1 = (D1*) pb ;
//     other options:
//     D1* pd1 = static_cast<D1*>( pb ) ;
//     D1* pd1 = dynamic_cast<D1*>( pb )  ;
//     D1* pd1 = reinterpret_cast<D1*>( pb )  ;
     /** do something with pd1 ; **/
}

main()
{
     foo( new D1() ) ;
     foo( new D2() ) ;

     return 1 ;
}

>> I believe then, that this iilegitimate casting can be performed with C style casting without the compiler cribbing about it.
Yes. One can say C-style casting is same as reinterpret_cast of C++ (where programmer is responsible for everything)

>> This is syntactic sugar for non-explicit constructors.
Technically, single arg non-explicit constructors are used as conversion operators (or they ARE the conversion operators). So it's normal and not syntactic sugar. That's how all conversion operators are defined, ain't they?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.