I would like to propose, in the spirit of Bjarne Stroustrup book,
an upcast (where target inherits source).
Upcasting is already directly supported by the language. Given classes Base
and Derived, with the public inheritance implied by their names, then:
Derived d;
Base * b=&d;
Base & br = d;
will work without any casting whatsoever. When the compiler compiles this
code, it has the definitions of classes Base and Derived available, so all
the work can be performed at compile time.
template
inline Target polymorphic_upcast(Source* x
BOOST_EXPLICIT_DEFAULT_TARGET)
{
typedef unsigned int uint;
uint offset = reinterpret_cast<uint>( static_cast(
reinterpret_cast<Target>(1) ) ) - 1;
Target res = reinterpret_cast<Target>(
reinterpret_cast<uint>( x ) -
offset );
assert( res == dynamic_cast<Target>(x) );
return res;
}
I don't understand this - how is casting a Target to an unsigned int going
to help? Did you perhaps mean Target * in the above example, or have I
missed something?
I would like to propose, in the spirit of Bjarne Stroustrup book,
an upcast (where target inherits source).
Upcasting is already directly supported by the language. Given classes Base
I don't understand this - how is casting a Target to an unsigned int going
to help? Did you perhaps mean Target * in the above example, or have I
missed something?
Yes, target is a pointer type, while Source isn't. That's because of the intended usage of this function which is A* a =
Here upcasting means casting a base class to a derived class, I know it may seem strange, bust boost offers a downcast
which does the static_cast the language does implicitly already (check ).
Upcasting is usually achieved by two ways: using reinterpret_cast directly, which is hazardous sometimes because the
pointer to the various base classes are not equal to the derived class when you use multiple inheritance. The other and
only safe way used is to use dynamic_cast.
The code I suggested propose a safe upcast without the constraints of dynamic_cast.
polymorphic_upcast( x );
Jean.
Here upcasting means casting a base class to a derived class, I know
it may seem strange, bust boost offers a downcast
which does the static_cast the language does implicitly already (check
).
I think you've got it backwards. Downcasting, in Boost at least, means
casting a pointer to a base class part of an object to a pointer to a
derived class part of the same object. The polymorphic_downcast is
*not* doing a static_cast for a conversion the language already does
implicitly.
Could you give a specific complete example (a file that would compile,
with all the declarations) of how one would use what you're proposing
to help make this clearer?
-- Darin
Here upcasting means casting a base class to a derived class, I know
it may seem strange, bust boost offers a downcast
which does the static_cast the language does implicitly already (check
).
I think you've got it backwards. Downcasting, in Boost at least, means
casting a pointer to a base class part of an object to a pointer to a
derived class part of the same object. The polymorphic_downcast is
*not* doing a static_cast for a conversion the language already does
implicitly.
template
inline Target polymorphic_downcast(Source* x
BOOST_EXPLICIT_DEFAULT_TARGET)
{
assert( dynamic_cast<Target>(x) == x ); // detect logic error
return static_cast<Target>(x);
}
Sorry about it, but it's here in the code. This is in the last version of
the CVS. It does a static_cast. The compiler does static_cast implicitly in
some cases.
For instance a C++ compiler replaces the assert line with:
assert( dynamic_cast<Target>(x) == static_cast<Target>(x) );
Could you give a specific complete example (a file that would compile,
with all the declarations) of how one would use what you're proposing
to help make this clearer?
I enclosed two files to this reply. Don't scream about chosen class names
and stuff in the example ;)
begin 666 test.cpp
M+R\@=&5S="YC<' @.B!$969I;F5S('1H92!E;G1R>2!P;VEN="!F;W(@=&AE
M(&-O;G-O;&4@87!P;&EC871I;VXN#0HO+PT*#0HC:6YC;'5D92 \;G%C87-T
M+F@^#0H-"@T*8VQAWT[#0H@(" @=FER='5A;"!V;VED('-T=69F*"D@>WT[#0H@(" @
M=FER='5A;"!V;VED('=H871E=F5R*"D@/3 [#0H@(" @=FER='5A;"!V;VED
M('=H871E=F5R,2@I(#TP.PT*<')O=&5C=&5D.@T*(" @(&EN="!I.PT*(" @
M(&-H87(@PT*<'5B;&EC.@T*(" @('9IWT[
M#0H@(" @=FER='5A;"!^0W5J*"D@>WT[#0I].PT*#0H-"@T*:6YT(&UA:6XH
M:6YT(&%R9V,L(&-H87(J(&%R9W9;72D-"GL-"B @("!#=6H@86)L83L-"B @
M("!#=6HJ('!A8FQA(#T@)F%B;&$[#0H@(" @0G5J*B!S:7-I(#T@8F]O7!E
M+FAP<#X-"@T*(R!I9B!D969I;F5D*$)/3U-47TU35D,I("8F($)/3U-47TU3
M5D,@/#T@,3(P," O+R Q,C P(#T@5D,V#0HC("!D969I;F4@3E%?15A03$E#
M251?1$5&055,5%]405)'150@+" Z.F)O;W-T.CIT>7!E/%1APT*(" @('5N
M
Here upcasting means casting a base class to a derived class, I know
it may seem strange, bust boost offers a downcast
which does the static_cast the language does implicitly already (check
).
I think you've got it backwards. Downcasting, in Boost at least, means
casting a pointer to a base class part of an object to a pointer to a
derived class part of the same object. The polymorphic_downcast is
*not* doing a static_cast for a conversion the language already does
implicitly.
template
inline Target polymorphic_downcast(Source* x
BOOST_EXPLICIT_DEFAULT_TARGET)
{
assert( dynamic_cast<Target>(x) == x ); // detect logic error
return static_cast<Target>(x);
}
Sorry about it, but it's here in the code. This is in the last version of
the CVS. It does a static_cast. The compiler does static_cast
implicitly in
some cases.
For instance a C++ compiler replaces the assert line with:
assert( dynamic_cast<Target>(x) == static_cast<Target>(x) );
Could you give a specific complete example (a file that would compile,
with all the declarations) of how one would use what you're proposing
to help make this clearer?
I enclosed two files to this reply. Don't scream about chosen class names
and stuff in the example ;)