Widening pointers

Home Page Narrow Gate Logic !>Jonatan*PL cattery<!  kurs "Filip"  Mail me

Home ] Up ] What's new ] Downloads ] Interests ] Education ] Projects ] Programming ] Arts ] Journeys ] Photos ] Jokes ] Friends ] Links ]

 

Problem

Solution

Example

Widening pointers

The problem

Sometimes one object needs services of another object. One of natural ways to implement this is to use pointer to that object. We can suppose pointer to this object is passed in constructor. And everything's fine till it is needed to descend a more functional class from the previous one and when that new class needs wider services from the object that it has pointer to. So the helper object also becomes a base for a more advanced class. But the problem is, how the new class can access new functionality? It has only pointer to the old helper object. There are many possible ways of resolving this: 

  1. Add a new pointer of type of new helper class - waste of memory - old and new pointer point to the same object.
  2. Add all functionality to the old helper class in form of pure virtual functions - better, but still wrong - if we would have to descend third generation, we would have to recompile all files, besides that, it is stupid for some generic object to have all methods used in hierarchy.
  3. Use multiple virtual inheritance - but it is to be used for more parallel relations between classes, and here, only one of them needs to know about the other. And, you cannot decide of the type of helper object at the run-time.
  4. Use templates - generally ok, but sometimes it is better or even needed to decide about types at run-time

Solution

My solution is a compilation of those above. It consumes zero memory and zero time, and it is completely safe from the point of view of programmer despite the use of static conversions.

The new class will use the inherited pointer to the old helper class. It should be converted statically to new helper class. A inline method can be added to make using that simpler - method, which converts the pointer to the old class and returns the new one. Alternatively, you can use properties.

But what with that safety, you might think. What, if one converts the new class to the old class, and assigns to the pointer object of old helper class, not the new one? The answer is: he don't.

We should make sure the only way to assign the helper object to the real object is in constructor of the real object. And each real object can be costructed only with helper class of specified kind. In this way, it is sure the object is right.

Example

There are two kinds of vehicles: cars and sportscars. Cars can drive on roads, but sports cars only on highways, that are of course roads, also. Cars cannot race, while sportscars can. One can race only on highways. That's the classes implementing this:

class vehicle;

class road {

    public:

        void drive(vehicle *);

};

 

class car : public vehicle { 

    protected:

        road *r;

 

        road *road() { return r; }

    public:

        void drive() { road()->drive(this); }

        car(road *r) : r(r) {}

};

 

class highway : public road {

    public:

        void race(vehicle *, vehicle *);

};

 

class sportscar : public car { 

    protected:

        highway *road() { return static_cast<highway *>(r); }

    public:

        void race(sportscar *co) { road()->race(this, co); }

        sportscar(highway *co) : car(co) {}

};

So, that is, I guess, all.

 

Home Page Top of page Back ] Up ] Next ]

Up ]

Page created 2001-03-17 17:02:36, last edited 2003-11-10 12:44:51   by Marcin Wudarczyk