Among static_cast, dynamic_cast, reinterpret_cast and const_cast, only static_cast is able to return an object of desirable type, whereas the other type can return only pointer or reference to representation. Why is it so?
Examples:
int y = 3;
double z = reinterpret_cast<double> (y);//error
double z = reinterpret_cast<double&> (y);//ok
double z = static_cast<double> (y);//but this is ok!!!
const int y = 3;
int z = const_cast<int> (y);//error
int z = const_cast<int&> (y);//ok
and for dynamic_cast:
using namespace std;
class Gun
{
public:
virtual void shoot(){
cout << "BANG!\n";
}
};
class MachineGun : public Gun{
public:
void shoot() override{
cout <<"3X-BANG\n";
}
};
int main()
{
Gun gun;
MachineGun tt;
Gun* gunp = &gun;
Gun* gunp1 = &tt;
Gun* newGun = dynamic_cast<Gun*>(gunp1);//ok
Gun newGun1 = dynamic_cast<Gun>(tt);//error
}
Only static_cast is able to return an object of desirable type
This is incorrect. All casts return an object when the cast target is an object type.
That said:
I'm making attempt to explain based on example, as addition to other answer that did explain nature of casts.
int y = 3;
double z = reinterpret_cast<double> (y);//error
This is not one of 11 allowed casts with reinterpret_cast
. Also std::bit_cast
can't cast it on most platforms as the int
typically does not have enough bits for double
. So it is unsure what you wanted to achieve.
double z = reinterpret_cast<double&> (y);//ok
This is present in list of valid reinterpret_cast
but likely causes undefined behavior for same reason why std::bit_cast
refuses. In typical implementation your z
is bigger than y
and so takes bits beyond memory location of y
.
double z = static_cast<double> (y);//but this is ok!!!
But that is fully valid. It is effectively same as
double z = y;
Compilers do not even warn about the latter. However when the value range of y
does not fully fit to z
then it is not clear if it was intentional. On such cases it is better to use former to indicate intent.
const int y = 3;
int z = const_cast<int> (y);//error
That is good. Absurd const_cast
does not compile! Or how does the effect that you tried to achieve differ from lot more readable
int z = y;
I would write that. Please describe the situation where you would write former.
int z = const_cast<int&> (y);//ok
Works, but is similarly unneeded and confusing like previous. I would only use const_cast for situations like that:
int x;
const int& y = x;
int& z = const_cast<int&> (y);
z = 42;
Here I know that thing referred by reference to const y
is really not const originally and so it is not undefined behavior to modify it to 42
.
About dynamic_cast
your example does not make sense at all what it wants to do:
Gun newGun1 = dynamic_cast<Gun>(tt);//error
It could be perhaps trying to do something like that:
Gun newGun1 = tt;
That compiles. However that would result with sliced out Gun
sub-object of MachineGun tt
assigned to newGun1
and that is usually programming error. What you tried to achieve with cast remains totally dark however.
Maybe the short answer is that static_cast
can take a type with no reference (and no pointer) because it is the only cast that can invoke a constructor of the target type.
Please correct me if I am wrong.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.