From: vsgdp on
Say you have 3 child classes A, B, C deriving from a parent class P
with pure virtual function f.

Suppose A::f(x1); // A::f depends only on x1
Suppose B::f(x1, x2); // B::f depends on x1 and x2
Suppose C::f(x1, x2, x3); // C::f depends on x1, x2, x3

Is it bad form to define P::f(x1, x2, x3), and then A::f and B::f just
ignore the parameters it does not need?

In some sense this could be justified; you could say that for A::f, x2
and x3 are just "zero" or some identity value that doesn't actually
affect the output.

Any thoughts on this?

I think it is okay occasionally if not abused often, but I would like
the opinion of the programming community.

For those that want some context, basically I have a Light class and I
derive:

DirectionalLight, PointLight, SpotLight, AreaLight. The area light
implementation requires some special data the others do not; this data
also varies over time so I can't just set it at construction time. I
can't set the area light's specific data at runtime either without
knowing its specific type (defeats polymorphism). So I am thinking
the best solution would be to just pass the data to the pure virtual
function, even though only area lights will use the data.

From: Daniel T. on
vsgdp <cloud00769(a)yahoo.com> wrote:

> Say you have 3 child classes A, B, C deriving from a parent class P
> with pure virtual function f.
>
> Suppose A::f(x1); // A::f depends only on x1
> Suppose B::f(x1, x2); // B::f depends on x1 and x2
> Suppose C::f(x1, x2, x3); // C::f depends on x1, x2, x3
>
> Is it bad form to define P::f(x1, x2, x3), and then A::f and B::f just
> ignore the parameters it does not need?
>
> In some sense this could be justified; you could say that for A::f, x2
> and x3 are just "zero" or some identity value that doesn't actually
> affect the output.
>
> Any thoughts on this?
>
> I think it is okay occasionally if not abused often, but I would like
> the opinion of the programming community.
>
> For those that want some context, basically I have a Light class and I
> derive:
>
> DirectionalLight, PointLight, SpotLight, AreaLight. The area light
> implementation requires some special data the others do not; this data
> also varies over time so I can't just set it at construction time. I
> can't set the area light's specific data at runtime either without
> knowing its specific type (defeats polymorphism). So I am thinking
> the best solution would be to just pass the data to the pure virtual
> function, even though only area lights will use the data.

The real question in my mind is, does the client programmer have to know
which kind of light he is dealing with? If so, then the extra parameters
are bad, otherwise they are simply information that the target doesn't
care about.
From: Dmitry A. Kazakov on
On 3 May 2007 14:46:20 -0700, vsgdp wrote:

> Say you have 3 child classes A, B, C deriving from a parent class P
> with pure virtual function f.
>
> Suppose A::f(x1); // A::f depends only on x1
> Suppose B::f(x1, x2); // B::f depends on x1 and x2
> Suppose C::f(x1, x2, x3); // C::f depends on x1, x2, x3
>
> Is it bad form to define P::f(x1, x2, x3), and then A::f and B::f just
> ignore the parameters it does not need?

That depends solely on P. A, B, C are the instances of the class P, so they
have no permission to speak.

> In some sense this could be justified; you could say that for A::f, x2
> and x3 are just "zero" or some identity value that doesn't actually
> affect the output.
>
> Any thoughts on this?
>
> I think it is okay occasionally if not abused often, but I would like
> the opinion of the programming community.
>
> For those that want some context, basically I have a Light class and I
> derive:
>
> DirectionalLight, PointLight, SpotLight, AreaLight. The area light
> implementation requires some special data the others do not; this data
> also varies over time so I can't just set it at construction time. I
> can't set the area light's specific data at runtime either without
> knowing its specific type (defeats polymorphism).

What is polymorphic here? [in the procedure f]

The light? Or the parameters of?

In your design you have answered it as yes, no. But maybe it is no, yes,
i.e.:

ParametersA::f (Light& L);
ParametersB::f (Light& L);
ParametersC::f (Light& L);

Or maybe yes. yes => double dispatching f in a parallel types hierarchy:

f (Light& L, Parameters& P);

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
From: H. S. Lahman on
Responding to Vsgdp...

> Say you have 3 child classes A, B, C deriving from a parent class P
> with pure virtual function f.
>
> Suppose A::f(x1); // A::f depends only on x1
> Suppose B::f(x1, x2); // B::f depends on x1 and x2
> Suppose C::f(x1, x2, x3); // C::f depends on x1, x2, x3
>
> Is it bad form to define P::f(x1, x2, x3), and then A::f and B::f just
> ignore the parameters it does not need?

From the perspective of P, this is fine. There is no law that says a
method has to access all of the available data. Case on point:

[P]
+ x1
+ x1
+ x3
+ doIt1()
+ doIt2()
+ doIt3()

Here doIt1 only needs x1, doIt2 only needs x1 and x2, and doIt3 needs
all three. The point is that attribute data and method arguments are
equivalent sources of data in OO applications. There is clearly no rule
that says an object method must use all the object's attributes.

OTOH, Daniel T. is correct that P is not the only player here. It takes
two to collaborate. As soon as one invokes P::f, we actually have:

[Client] ----------------- [P]
+ f(...)
A
|
+--------+----------+
| | |
[A] [B] [C]

The problem is a C /needs/ viable values of x2 and x3 and the only place
those can come from is Client. That means that a given Client must know
which subclass it is actually dealing with in order to know whether it
should provide proper values or just a flag. In that case, you should
not provide such a P. Instead, Client should navigate directly to
whichever subclass of [P] the context provides and do the right thing.

But suppose we change one thing:

[Client] ----------------- [P]
+ x1 + f(...)
+ x2 A
+ x3 |
+--------+----------+
| | |
[A] [B] [C]

Now [Client] always has valid values of x1, x2, and x3. There is then no
harm in passing all of them to P::f(...). The individual subclass will
just eat those it needs.

The key difference here is that in the first version Client needs to
make a decision (i.e., to use a flag value or a real value) and that
decision depends upon knowing which subclass of [P] one has in hand. In
the second version, though, Client makes no such decision; it always
passes valid values.

Note that you can avoid this entire issue if you don't pass values at
all during object-to-object collaborations. If you let [A], [B], and [C]
access the data in the form of attribute values directly from the owning
object, the whole problem goes away. That becomes clear in my last
version above where the location of the attributes is just moved
compared to my first example.

In fact, in OOA/D one seeks to avoid data packets with messages because
that makes it difficult to deal with data integrity if one needs to
implement distributed or concurrent processing during OOP. Such
processing may introduce arbitrary delays between when the values are
accumulated and when the message is actually consumed. [The main
exception is when requirements demand a "snapshot", such as sensors
whose samples must all be from the same time slice for consistency.] If
one does the OOA/D without message data packets, one can <relatively>
easily provide any necessary synchronization infrastructure when things
get hairy in the actual computing environment.

Conversely, if there is a performance problem due to the extra
relationship navigation to invoke the getters, one can provide the data
in the data packets -- after carefully ensuring there won't be data
integrity problems due to delays.


*************
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
hsl(a)pathfindermda.com
Pathfinder Solutions
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
"Model-Based Translation: The Next Step in Agile Development". Email
info(a)pathfindermda.com for your copy.
Pathfinder is hiring:
http://www.pathfindermda.com/about_us/careers_pos3.php.
(888)OOA-PATH



From: carmen miranda on
sounds like the issue is not what you are working on, but how you are going
at it..you want to distinguish the new state which results from any of these
parameters. you get a simulator running, and consider the old parameter,
now changes in it. now add a second parameter. you are creating the
problem space see a book by john k. lyon on the 3-D problem space. they
have a copy at a college library somewhere. i have a zerox copy . try not
to hit the walls of the 3-d conceptual spaces game is over!!


"vsgdp" <cloud00769(a)yahoo.com> wrote in message
news:1178228780.557870.85530(a)h2g2000hsg.googlegroups.com...
> Say you have 3 child classes A, B, C deriving from a parent class P
> with pure virtual function f.
>
> >