So, I had an exam the other day, and one of the questions was something very similar to this:
We have a class called Square
which holds a variable int side
. How can we make it possible that cout << static_cast<int>(aSquare) <<endl;
would print out the area of aSquare?
Is that even possible?
As we learnt in the generic types example, static_cast<> will fail if you try to cast an object to another unrelated class, while reinterpret_cast<> will always succeed by "cheating" the compiler to believe that the object is really that unrelated class.
C-style casts also ignore access control when performing a static_cast , which means that they have the ability to perform an operation that no other cast can.
The static_cast operator converts variable j to type float . This allows the compiler to generate a division with an answer of type float . All static_cast operators resolve at compile time and do not remove any const or volatile modifiers.
static_cast − This is used for the normal/ordinary type conversion. This is also the cast responsible for implicit type coersion and can also be called explicitly. You should use it in cases like converting float to int, char to int, etc. dynamic_cast −This cast is used for handling polymorphism.
It's possible to make that work, but not via overloading static_cast<>()
. You do so by overloading the typecast operator:
class Square
{
public:
Square(int side) : side(side) {}
operator int() const { return side * side; } // overloaded typecast operator
private:
int side;
};
// ...
// Compiler calls Square::operator int() to convert aSquare into an int
cout << static_cast<int>(aSquare) <<endl;
Beware that overloaded typecast operators more often than not tend to do more harm than good. They make lots of nonsensical implicit cast operations possible. When you read this code snippet below, do you think "a is going to get the area of s"?
Square aSquare;
int a = aSquare; // What the heck does this do?
I certainly don't. This makes way more sense and is much more readable:
Square aSquare;
int a = aSquare.GetArea();
Not to mention that typically you want to be able to access other information about Square
, like GetSide()
or GetApothem()
or GetPerimeter()
or whatever. operator int()
obviously can return only one int
, and you can't have multiple operator int()
s as members of a class.
Here's another situation where the operator int()
makes code that compiles yet makes no sense whatsoever:
Square s;
if(s > 42) {} // Huh?!
What does it mean for a Square
to be greater than 42? It's nonsense, but with the operator int()
the code above will compile as Shape
is now convertible to an int
which can be compared to another int
with a value 4
.
So don't write typecast operators like that. In fact if you're overloading typecast operators you may want to think twice about what you're doing. There's actually only a few cases where overloading the typecast operator is useful in modern C++ (e.g. the safe bool idiom).
You can overload the cast operator:
struct square {
operator int() const {
return (side * side);
}
int side;
};
The only problem is that it will be used implicitly, and casting doesn't make much sense here. You also can't distinguish between the different types of casts (static_cast, c-style, etc)
This is the preferred way to do things:
struct square {
int get_area() const {
return (side * side);
}
int side;
}
If you must use a cast, use C++11 feature and mark it explicit
. This prevents implicit casting mistakes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With