3

My teacher included the lines below in one of our examples of casting. c is an object of class Circle which inherits from class Point. In my search for an answer to the question "Can I cast an object of class Point to type Circle?" I found that he uses a different syntax than every website I've been on. The websites all use static_cast and dynamic_cast syntax. He won't be using static_cast and dynamic_cast on the test and I'm just wondering what he is using and how that operates.

Also, if you have an answer to whether I can cast a base object to a derived type, I thank you immensely.

output << "the center of the circle is at " << (Point) c; 
// casting `Circle` object `c` with type `(Point)`, calls the first overloaded >stream insertion operator"
user0042
  • 7,917
  • 3
  • 24
  • 39
Marcus Kim
  • 283
  • 2
  • 12
  • [Casting base to derived is UB](https://stackoverflow.com/questions/5313322/c-cast-to-derived-class), that's why you use virtual methods instead. That is not the case here though, this is derived to base. – Patrick Roberts Dec 17 '17 at 05:16
  • @PatrickRoberts casting base to derived with this syntax is ill-formed (i.e. `(Derived)b` or `static_cast(b)` gives an error) – M.M Dec 17 '17 at 05:57

3 Answers3

6

(Point)c is known as a "C-style" cast. This can basically be thought of as a brute force cast that does whatever it can to make the cast succeed. This means it could end up causing a static_cast a const_cast or even a reinterpret_cast.

When the C-style cast expression is encountered, the compiler attempts to interpret it as the following cast expressions, in this order:

  • const_cast
  • static_cast
  • static_cast followed by const_cast
  • reinterpret_cast
  • reinterpret_cast followed by const_cast

Source: https://en.cppreference.com/w/cpp/language/explicit_cast

And from Stroustrup himself:

Explicit type conversions (often called casts to remind you that they are used to prop up something broken) are best avoided.

and

C-style casts should have been deprecated in favor of named casts.

Stroustrup, Bjarne. A Tour of C++ (C++ In-Depth Series) (Kindle Location 7134). Pearson Education. Kindle Edition.

So the named casts are recommended. In practice I still encounter professional code using C-style casts simply because it makes code more succinct and readable and is -- if you know what you're doing -- normally equivalent to static_cast in the places its used. For what its worth I think C-style casts are okay if used for these reasons in a context that makes it obvious that it will result in a static_cast, and Stroustrup is coming from an overly object-oriented perspective in his general disdain for casting. But you should prefer the named casts.

Your teacher is probably using the C-style cast as a less scary-looking introduction to casting.

sleep
  • 4,855
  • 5
  • 34
  • 51
  • 1
    *"I need something less scary to teach casts... I know, I'll use the legacy werewolf cast which can hurl you straight to UB-land if you shake it the wrong way!"* ah, C++ teachers... – Quentin Dec 17 '17 at 05:59
  • 1
    Even though correct, I don't think blogs are great authorative sources especially when they are so opinionated – Passer By Dec 17 '17 at 06:03
3

The answers so far didn't cover what (Point) c; actually does. Assuming Circle does not explicitly define operator Point:

This is the same as static_cast<Point>(c). It creates a temporary Point object which is initialized by Point's copy-constructor, with c as the argument. This works because the base class copy-constructor can, for better or worse, bind to a derived object.

To be clear, it is NOT a reference of any sort to the Point part of the Circle. It is making a copy of the Point part of the Circle. This is called slicing. It loses all the "Circle" part of the information.

I would advise not doing this. The code would be better off without the cast. I guess perhaps there is defined operator<< overloads for both Point and Circle and he wants to explicitly select the Point one; in that case you should use static_cast<Point&>(c) or the equivalent (Point&)c to view the circle instead of slicing it.

NB. Deriving Circle from Point in the first place is also suspicious; inheritance should represent an "is-a" relationship (not "has-a"); but a circle is not a point.

Further reading: What is object slicing?

M.M
  • 138,810
  • 21
  • 208
  • 365
-1

That is a C-style cast and will use "c.operator Point()" if available, otherwise it will behave the same as "reintrepret_cast(c)"

SoronelHaetir
  • 14,104
  • 1
  • 12
  • 23
  • No, it will not do a reinterpret_cast here. `Circle` is derived from `Point`, so the cast does a direct conversion, just like `Point p = c;` would do. – Pete Becker Dec 17 '17 at 17:28