In JOINT STRIKE FIGHTER AIR VEHICLE C CODING STANDARDS Bjarne states, that:
Down casting (casting from base to derived class) shall only be allowed through one of the following mechanism:
- Virtual functions that act like dynamic casts (most likely useful in relatively simple cases)
- Use of the visitor (or similar) pattern (most likely useful in complicated cases)
I can't wrap my head around first proposition. Googling it presented no examples, nor explanation.
How can virtual function act like a dynamic cast?
CodePudding user response:
You can use a virtual function to downcast like this:
struct Bar;
struct Foo {
virtual Bar* as_bar() { return nullptr; }
};
struct Bar : Foo {
Bar* as_bar() override { return this; }
};
Not often used, in practice.
CodePudding user response:
It's referring to a technique that was kind of common in the early days of C , before dynamic_cast
, RTTI
, etc., were added to the language.
The basic idea looks something like this:
class Derived1;
class Derived2;
class Base {
public:
virtual Derived1 *toDerived1() const { return nullptr; }
virtual Derived2 *toDerivde2() const { return nullptr; }
};
class Derived1 : public Base {
public:
Derived1 *toDerived1() const override { return this; }
Derived2 *toDerived2() const override { return nullptr; }
};
class Derived2 : public Base {
public:
Derived1 *toDerived1() const override { return nullptr; }
Derived2 *toDerived2() const overrode { return this; }
};
This lets you do something just about like a dynamic_cast
on a pointer, yielding a pointer to the expected type if the pointee object is actually of that type, and otherwise a nullptr
.
This has obvious disadvantages though. Every class involved has to be aware of every other class. Adding a new class means adding a new function to every class. Unless the entire class structure is quite static (and a small number of classes altogether), this can quickly turn into a maintenance nightmare.
Reference
This technique was covered in Effective C , 1st Edition, Item 39. I haven't checked to be sure, but it was probably dropped from the newer editions, as (at least in the minds of most programmers) the addition of dynamic_cast
rendered it obsolescent (at best).