Re: Subset of derived classes accessing base class functions
On Jul 24, 10:44 pm, fgh.vbn....@gmail.com wrote:
James Kanze wrote:
On Jul 24, 9:08 pm, fgh.vbn....@gmail.com wrote:
Say I have a base class B and four derived classes d1, d2, d3, d4. I
have three functions fx, fy, fz such that:
fx should only be called by d1, d2
fy should only be called by d2, d3
fz should only be called by d1, d3, d4
Then you have a fundamental design problem. Something is
wrong with this scenario. The base class doesn't know about
the derived classes, so it can't impose any restrictions on
a subset of them. And if the restriction comes from the
derived class itself, then the class knows about it, and
will conform to it.
[...]
Is there any other alternate way to do something like
this? May be a design pattern that can be adapted to
handle such a situation?
Perhaps you'd best describe the problem you're trying to
solve, and not just the solution which doesn't work.
Perhaps you are right :-(. Let me write out the problem in
better terms.
Say I have a base class called Car.
I have four different cars Car1, Car2, Car3, Car4.
There are three types of tyres TyreX, TyreY, TyreZ.
TyreX can only "be applied to" Car1, Car2.
TyreY only to Car2, Car3.
TyreZ only to Car1, Car3, Car4.
The first question is: why won't all of the tire types work with
all of the car types? Since you've used suggestive names from a
domain I vaguely know (I own a car), I can guess: each car has a
certain number of constraints concerning the tires it can use
(size being the most obvious one).
You can solve this either at runtime or through the type system.
Normally, static verification (type errors) are to be preferred
to run-time errors, but think about it for awhile: suppose your
code has a pointer to a Car, and you want to apply some Tire* to
it. Given that you don't know the actual type of either Car or
Tire until runtime, how can the compiler tell whether there is a
mismatch or not.
The usual solution here is to provide a virtual function in Car,
which returns the size, etc. (or a list of the sizes, etc.)
which it can accept for Tire. And of course, a function in Tire
which returns its size, etc. Which means a runtime check. But
again, this more or less corresponds to reality: if you go to buy
tires for your car, you won't go to a tire shop specialized in
selling only tires for that particular make and model of car;
you'll go to a general tire shop, pick out a set of tires, and
then check whether they meet the constraints given in your
owners manual (a runtime check).
Note that there can be exceptions: if you can provide a compile
time check, by all means do so. But this generally means
defining additional interfaces, derived from Car and Tire (e.g.
F1RacingCar, F1RacingTires). At that point, code which knows
it's dealing with F1RacingCars and F1RacingTires can get the
compile time check, and avoid the runtime one. (But such code
won't use the basic Car/Tire interface, but rather the derived
interface.)
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34