Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overloading static_cast?

Tags:

c++

casting

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?

like image 834
Radix Avatar asked Dec 10 '11 17:12

Radix


People also ask

What happens when static_cast fails?

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.

What happens when you perform a static_cast?

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.

What is the purpose of static_cast?

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.

What is the difference between static_cast and Dynamic_cast?

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.


2 Answers

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).

like image 179
In silico Avatar answered Sep 18 '22 19:09

In silico


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.

like image 30
Pubby Avatar answered Sep 20 '22 19:09

Pubby