Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't C++ allow you to request a pointer to the most derived class?

(This question should probably be answered with a reference to Stroustrup.)

It seems extremely useful to be able to request a pointer to the most derived class, as in the following:

class Base { ... };
class DerivedA { ... };
class DerivedB { ... };
class Processor
{
  public:
  void Do(Base* b) {...}
  void Do(DerivedA* d) {...}
  void Do(DerivedB* d) {...}
};

list<Base*> things;
Processor p;
for(list<Base*>::iterator i=things.begin(), e=things.end(); i!=e; ++i)
{
    p.Do(CAST_TO_MOST_DERIVED_CLASS(*i));
}

But this mechanism isn't provided in c++. Why?

Update, Motivating Example:

Suppose instead of having Base and Derived and Processor, you have:

class Fruit
class Apple : public Fruit
class Orange: public Fruit

class Eater
{
   void Eat(Fruit* f)  { ... }
   void Eat(Apple* f)  { Wash(f); ... }
   void Eat(Orange* f) { Peel(f); ... }
};

Eater me;
for each Fruit* f in Fruits
    me.Eat(f);

But this is tricky to do in C++, requiring creative solutions like the visitor pattern. The question, then, is: Why is this tricky to do in C++, when something like "CAST_TO_MOST_DERIVED" would make it much simpler?

Update: Wikipedia Knows All

I think Pontus Gagge has a good answer. Add to it this bit from the Wikipedia entry on Multiple Dispatch:

"Stroustrup mentions that he liked the concept of Multi-methods in The Design and Evolution of C++ and considered implementing it in C++ but claims to have been unable to find an efficient sample implementation (comparable to virtual functions) and resolve some possible type ambiguity problems. He goes on to state that although the feature would still be nice to have, that it can be approximately implemented using double dispatch or a type based lookup table as outlined in the C/C++ example above so is a low priority feature for future language revisions."

For background, you can read a little summary about Multi-Methods, which would be better than a call like the one I mention, because they'd just work.

like image 489
Matthew Lowe Avatar asked Jun 16 '10 14:06

Matthew Lowe


2 Answers

Probably because that's what virtual functions do for you instead. The implementation of the virtual function that is nearest the most-derived class will be called when you invoke it through a base class pointer or reference.

like image 118
Troubadour Avatar answered Oct 15 '22 20:10

Troubadour


Firstly, C++ does allow you to request a pointer to a most derived class in numerical terms (i.e. just the numerical value of the address). This is what dynamic_cast to void* does.

Secondly, there's no way to obtain a pointer to the most derived class in therms of exact type of the most derived class. In C++ casts work with static types, and static type is a compile-time concept. Type-based function overloading is also a compile-time process. The exact most derived type is not known at compile-time in your case, which is why cannot cast to it and can't resolve overloading on it. The request to have such a cast makes no sense in the realm of C++ language.

What you are trying to implement (if I understood your intent correctly), is implemented by completely different means, not by a cast. Read about double dispatch, for one example.

like image 32
AnT Avatar answered Oct 15 '22 20:10

AnT