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
vijayan121
Posting Virtuoso
1,606 posts since Dec 2006
Reputation Points: 1,159
Solved Threads: 287
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.
thekashyap
Practically a Posting Shark
811 posts since Feb 2007
Reputation Points: 254
Solved Threads: 75
>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.
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
>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?
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
hinduengg
Junior Poster in Training
88 posts since Jun 2007
Reputation Points: 36
Solved Threads: 4
>> 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?
thekashyap
Practically a Posting Shark
811 posts since Feb 2007
Reputation Points: 254
Solved Threads: 75