The copier is broken << | Home | >> A big unit on Object Oriented Design
2017-10-31 (happy halloween!)
BOO! -Brad Lushman
For simplicity: Assume the old book hiearchy
-
Book
Text
Comic
-
C-style Casting
(type) expr
- Forces
expr
to be treated as typetype
- Ex.
C++ int *p; int q = (int) p;
- Very easy to be a source of error
- Very difficult to search for
The C++
casting operators - 4 operators
static_cast
: for conversion with well-defined semantics- Ex.
void f(int a); void f(double d); int x; f(static_cast<double>(x));
- Ex.
// superclass pointer to a subclass pointer Book *b = new Text { ... }; Text *t = static_cast<Text *>(b);
- You do this if you're 100% sure that pointer is pointing to a
Text
, otherwise it is not safe
- Ex.
reinterpret_cast
: for casts without well-defined semantics- Unsafe, implementation-dependent (therefore unportable)
- Ex.
Book *b = new Book { ... }; int *p = reinterpret_cast<int *>(b);
const_cast
: for adding/removing const- The only C++ cast that can "cast away
const
" - If item is still in read-only memory, it's still read only
- Ex.
void g(Book &b); // Assuming we know g won't change b void f(const Book &b) { g(const_cast<Book &>(b)); }
- The only C++ cast that can "cast away
dynamic_cast
:Book *pb = ...
- What if we don't know whether
pb
points to aText
? static_cast
is not safeText *pt = dynamic_cast<Text*>(pb);
- If
*pb
is aText
or a subclass ofText
, cast succeeds.pt
points at the object, elsept = nullptr
.if (pt) { ... pt->getTopic() ... } else ... // Not a Text
- Ex.
void whatIsIt(Book *pb) { if (dynamic_cast<Text*>(pb)) cout << "Text"; else if (dynamic_cast<Comic*>(pb)) cout << "Comic"; else cout << "Book"; }
- Not good style, what happens when you create a new
Book
type?
- Not good style, what happens when you create a new
- Dynamic reference casting
Book *pb = ____; Text &t = dynamic_cast<Text &>(*pb); if (*pb is a Text) // ok else // rase std::bad_cast
- Note: dynamic casting works by accessing an objects Run-Time Type Information (RTTI), this is stored in the vtable for the class
- This means we can only
dynamic_cast
on objects that have at least one virtual method
- This means we can only
- Dynamic reference casting offers a possible solution to take polymorphic assignment problem:
Text &Text::operator=(Book other) { // Virtual Text &textother = dynamic_cast<Text &>(other); // Throws if other is not a Text if (this == &textOther) return *this; Book::operator=(std::move(textother)); topic = std::move(textother.topic); return this; }
- What if we don't know whether
The copier is broken << | Home | >> A big unit on Object Oriented Design