C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

RTTI v.s. Liskov Principle
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
JesseChen
Guest





PostPosted: Thu Oct 16, 2003 2:39 pm    Post subject: RTTI v.s. Liskov Principle Reply with quote



Hi,

I know that there is a Liskov substitution principle. This principle is
the
guild line of OOD which says "Functions that use pointers or references
to
base classes must be able to use objects of derived classes without
knowing
it".

But in C++, there is RTTI that violates this principle.

I would be glad if you can make some comments on how to use RTTI and
Liskov
substitution principle.

thanks

Jesse

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
WW
Guest





PostPosted: Thu Oct 16, 2003 8:46 pm    Post subject: Re: RTTI v.s. Liskov Principle Reply with quote



JesseChen wrote:
Quote:
Hi,

I know that there is a Liskov substitution principle. This principle
is the guild line of OOD which says "Functions that use pointers or
references to base classes must be able to use objects of derived
classes without knowing it".

But in C++, there is RTTI that violates this principle.

I would be glad if you can make some comments on how to use RTTI and
Liskov substitution principle.

Simple. Read the above again. it does not say: they have no way to
know
it. It only says that whatever the base class interface promises, the
derived classes will deliver.

--
WW aka Attila



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Thant Tessman
Guest





PostPosted: Fri Oct 17, 2003 7:55 am    Post subject: Re: RTTI v.s. Liskov Principle Reply with quote



WW wrote:
Quote:
JesseChen wrote:

Hi,

I know that there is a Liskov substitution principle. This principle
is the guild line of OOD which says "Functions that use pointers or
references to base classes must be able to use objects of derived
classes without knowing it".

But in C++, there is RTTI that violates this principle.

I would be glad if you can make some comments on how to use RTTI and
Liskov substitution principle.


Simple. Read the above again. it does not say: they have no way to
know
it. It only says that whatever the base class interface promises, the
derived classes will deliver.

Actually, RTTI *does* violate LSP as it was originally stated: if a
value of type 'B' can be used anywhere a value of type 'A' is expected
without changing the behavior of a program, then 'B' is a subtype of
'A'. The problem is of course that if 'B' doesn't change anything, why
distinguish it from 'A' in the first place?

At this point the discussion turns religious.

-thant


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
WW
Guest





PostPosted: Fri Oct 17, 2003 11:43 am    Post subject: Re: RTTI v.s. Liskov Principle Reply with quote

Thant Tessman wrote:
Quote:
WW wrote:
JesseChen wrote:

Hi,

I know that there is a Liskov substitution principle. This
principle >>is the guild line of OOD which says "Functions that use
pointers or >>references to base classes must be able to use objects
of derived >>classes without knowing it".

But in C++, there is RTTI that violates this principle.

I would be glad if you can make some comments on how to use RTTI
and >>Liskov substitution principle.


Simple. Read the above again. it does not say: they have no way
to > know
it. It only says that whatever the base class interface promises,
the > derived classes will deliver.

Actually, RTTI *does* violate LSP as it was originally stated: if a
value of type 'B' can be used anywhere a value of type 'A' is expected
without changing the behavior of a program, then 'B' is a subtype of
'A'. The problem is of course that if 'B' doesn't change anything, why
distinguish it from 'A' in the first place?

I think that is a misunderstanding of the LSP. And LSP on LSD. Wink In C++
you _cannot_ use class B in place of class A. Only a pointer or a reference
to class A pointing or refering to a class B can be used as a pointer or a
reference to a class A, without knowing it really refers or points to a
class B.

LSP - as I understand it - talks about interface equality. Call it
interface definitions and observable, guaranteed post conditions. The RTTI
is not part of the classes interface, it is a language machinery. And in
C++ the classes interface can only "show up" independly of the class as a
pointer or a reference.

Also IMO LSP has to be "translated" to the language one uses. In theory it
would be possible to create a language which needs no predefined class
types, every objct carries around its class definition and everything is
bound runtime. The CA-Clipper solution of OOB was very close to that
"ideal". In such a language objects will most probably have no sizeof, they
might have RTTI... but they will certainly be represented by references to
themselves. Much like in template programming, we have another -
non-inheritance based LSP surfacing there.

Quote:
At this point the discussion turns religious.

Not necessarily. LSP is a high level principle, which has to be
"translated" for the target language. It can even be translated to generic
programming, which already shows it is pretty generic (no pun intended), not
only OO. Of coruse, we can make a religious discussion about it. Smile But
IMO it is rather philosophy.

--
WW aka Attila



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Aaron Bentley
Guest





PostPosted: Fri Oct 17, 2003 3:03 pm    Post subject: Re: RTTI v.s. Liskov Principle Reply with quote

Thant Tessman wrote:
Quote:
WW wrote:
JesseChen wrote:

Hi,

I know that there is a Liskov substitution principle. This principle
is the guild line of OOD which says "Functions that use pointers or
references to base classes must be able to use objects of derived
classes without knowing it".

But in C++, there is RTTI that violates this principle.

I would be glad if you can make some comments on how to use RTTI and
Liskov substitution principle.


Simple. Read the above again. it does not say: they have no way to
know
it. It only says that whatever the base class interface promises, the
derived classes will deliver.

Actually, RTTI *does* violate LSP as it was originally stated: if a
value of type 'B' can be used anywhere a value of type 'A' is expected
without changing the behavior of a program, '

Where did you get the "without changing the behavior of a program"?
Obviously the point of polymorphism is that the behaviour will change.

Quote:
then 'B' is a subtype of
'A'. The problem is of course that if 'B' doesn't change anything, why
distinguish it from 'A' in the first place?

Even granting the other, the point would be that B can have additional
functionality that is used when treating it as a B, but not used when
treating it as an A.

Aaron
--
Aaron Bentley
www.aaronbentley.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Thant Tessman
Guest





PostPosted: Fri Oct 17, 2003 3:31 pm    Post subject: Re: RTTI v.s. Liskov Principle Reply with quote

WW wrote:
Quote:
Thant Tessman wrote:


[...]

Quote:
Actually, RTTI *does* violate LSP as it was originally stated: if a
value of type 'B' can be used anywhere a value of type 'A' is expected
without changing the behavior of a program, then 'B' is a subtype of
'A'. The problem is of course that if 'B' doesn't change anything, why
distinguish it from 'A' in the first place?


I think that is a misunderstanding of the LSP. [...]

No, it's almost a direct quote. The problem is that as originally
stated, the LSP is far to restrictive to be useful. And like all
religious scripture, what one decides what it *really* means determines
the sect to which one is ordained.

-thant


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Thant Tessman
Guest





PostPosted: Fri Oct 17, 2003 4:48 pm    Post subject: Re: RTTI v.s. Liskov Principle Reply with quote

Aaron Bentley wrote:
Quote:
Thant Tessman wrote:

[...]

Quote:
Actually, RTTI *does* violate LSP as it was originally stated: if a
value of type 'B' can be used anywhere a value of type 'A' is expected
without changing the behavior of a program, '


Where did you get the "without changing the behavior of a program"?

http://burks.brighton.ac.uk/burks/foldoc/20/67.htm

Quote:
Obviously the point of polymorphism is that the behaviour will change.

And just as obviously, this violates LSP as originally stated--hence the
OP's question.

Note that this is not to argue that virtual functions in C++ are wrong
or bad. It is to argue that the LSP is not *by itself* a foundation for OO.


Quote:
then 'B' is a subtype of
'A'. The problem is of course that if 'B' doesn't change anything, why
distinguish it from 'A' in the first place?


Even granting the other, the point would be that B can have additional
functionality that is used when treating it as a B, but not used when
treating it as an A.

Yes, it's hard to imagine LSP being meaningful at all without at least this.

-thant


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Aaron Bentley
Guest





PostPosted: Sat Oct 18, 2003 9:46 pm    Post subject: Re: RTTI v.s. Liskov Principle Reply with quote

Thant Tessman wrote:
Quote:
Aaron Bentley wrote:

Thant Tessman wrote:


[...]


Actually, RTTI *does* violate LSP as it was originally stated: if a
value of type 'B' can be used anywhere a value of type 'A' is expected
without changing the behavior of a program, '


Where did you get the "without changing the behavior of a program"?


http://burks.brighton.ac.uk/burks/foldoc/20/67.htm

Thanks for the link. I hadn't read that before. Let's get the original
formulation quoted here:

If for each object o1 of type S there is an object o2 of type T such
that for all programs P defined in terms of T, the behaviour of P is
unchanged when o1 is substituted for o2 then S is a subtype of T.

Quote:
Obviously the point of polymorphism is that the behaviour will change.


And just as obviously, this violates LSP as originally stated--hence the
OP's question.

I tend to agree. Looks like Liskov's description of a subtype is
stricter than the C++ version. And it looks like the Howe
interpretation ignores the key "the behavior is unchanged" bit, and so
draws incorrect conclusions. (Note that the OP was talking about RTTI
though.)

Aaron
--
Aaron Bentley
www.aaronbentley.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Shane Beasley
Guest





PostPosted: Sun Oct 19, 2003 1:11 pm    Post subject: Re: RTTI v.s. Liskov Principle Reply with quote

Aaron Bentley <aaron.bentley (AT) utoronto (DOT) ca> wrote


Quote:
Obviously the point of polymorphism is that the behaviour will change.

Ah, but that's not the point at all. :)

As per the C++ FAQ[1], subtype polymorphism is about allowing old code
to call new code. Old code specifies behavior; new code specifies only
how it will implement that behavior. If the new code behaves
differently than the old code expects, the protocol breaks down.

- Shane

1. http://www.parashift.com/c++-faq-lite/big-picture.html#faq-6.9

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Aaron Bentley
Guest





PostPosted: Sun Oct 19, 2003 9:46 pm    Post subject: Re: RTTI v.s. Liskov Principle Reply with quote

Shane Beasley wrote:
Quote:
Aaron Bentley <aaron.bentley (AT) utoronto (DOT) ca> wrote


Obviously the point of polymorphism is that the behaviour will change.

Ah, but that's not the point at all. :)

As per the C++ FAQ[1], subtype polymorphism is about allowing old code
to call new code. Old code specifies behavior; new code specifies only
how it will implement that behavior. If the new code behaves
differently than the old code expects, the protocol breaks down.

The bit about old code specifying behaviour is not in the FAQ, and I
disagree with it. The old code specifies operations that the new code
must support, but doesn't prescribe what those operations should do.

So long as the behaviour with respect to the old code is correct, the
protocol will not break down, but "behaviour" is much more than
"behaviour-with-respect-to-old-code".

If there is no difference in interface or behaviour betweeen two
classes, then why have two classes?

Aaron
--
Aaron Bentley
www.aaronbentley.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Matthias Hofmann
Guest





PostPosted: Tue Oct 21, 2003 3:25 pm    Post subject: Re: RTTI v.s. Liskov Principle Reply with quote


Aaron Bentley <aaron.bentley (AT) utoronto (DOT) ca> schrieb in im Newsbeitrag:
ueykb.64$aw5.17248 (AT) news20 (DOT) bellglobal.com...
Quote:
Shane Beasley wrote:
Aaron Bentley <aaron.bentley (AT) utoronto (DOT) ca> wrote


Obviously the point of polymorphism is that the behaviour will
change.

Ah, but that's not the point at all. :)

As per the C++ FAQ[1], subtype polymorphism is about allowing old code
to call new code. Old code specifies behavior; new code specifies only
how it will implement that behavior. If the new code behaves
differently than the old code expects, the protocol breaks down.

The bit about old code specifying behaviour is not in the FAQ, and I
disagree with it. The old code specifies operations that the new code
must support, but doesn't prescribe what those operations should do.


To be more precise, the old code does not prescribe what should happen
"under the hood", it only prescribes what should "appear" to happen. In
other words, it expects a certain input to lead to a certain result, no
matter what algorithm the new code choses.

Quote:
So long as the behaviour with respect to the old code is correct, the
protocol will not break down, but "behaviour" is much more than
"behaviour-with-respect-to-old-code".

If there is no difference in interface or behaviour betweeen two
classes, then why have two classes?


Because the same behaviour can be accomplished in different ways. The two
classes chose different ways.

Regards,

Matthias



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Isaac Rodriguez
Guest





PostPosted: Wed Oct 22, 2003 1:25 am    Post subject: Re: RTTI v.s. Liskov Principle Reply with quote

My interpretation is that the behavior of the program does not change
because of an algorithm changes. Let me explain. You can have the
classic
hierachy of Shape that has a Circle and Rectangle classes derived from
it.
The driver program prints a report where it shows the Shape's ID and the
Shape's area. So you basically have something like this:

class Shape
{
public:
int id () const = 0;
int area () const = 0;
// Whatever else you need.
}

class Circle : public Shape
{
// Overwritte id and area
}

class Rectangle : public Shape
{
// Overwritte id and area
}

So now, your driver program looks something like this.

int main ()
{
std::vector<Shape*> MyShapes;
getMyShapes(MyShapes)
std::vector::const_iterator iter = MyShapes.begin();
for (; iter != MyShapes.end(); ++iter) {

std::cout << iter->id() << " " << iter->area() << std::endl;
}

return 0;
}

The algorithm to calculate the area of a circle is different than the
algorithm to calculate the area for a rectangle. That's obvious. But the
semantics of the area() method do not change, so the program's behavior
would not change. It would be different if we overwritte the area()
method
of the Rectangle class to return the height of the rectangle instead of
the
area. That would violate LSP. IMO, a change of algorithm not necessarily
implies a change in program behavior. It may mean a change in object
behavior, but we always want to maintain the semantics intact.

--
Regards,

Isaac Rodriguez
=======================
Software Engineer - Autodesk



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Thant Tessman
Guest





PostPosted: Wed Oct 22, 2003 1:30 am    Post subject: Re: RTTI v.s. Liskov Principle Reply with quote

Matthias Hofmann wrote:
Quote:
Aaron Bentley <aaron.bentley (AT) utoronto (DOT) ca> schrieb in im Newsbeitrag:
ueykb.64$aw5.17248 (AT) news20 (DOT) bellglobal.com...


[...]

Quote:
If there is no difference in interface or behaviour betweeen two
classes, then why have two classes?


Because the same behaviour can be accomplished in different ways. The
two classes chose different ways.

Consider the pedagogically ubiquitous Shape class with a virtual
function "draw" supplied by the sibling descendents Circle and Square.
You may want to argue that each sibling is distinguised not by behavior,
but by implementation. However, it seems more reasonable to think of
each as as implementing different behaviors invoked by a single but
context-sensitive message "draw."

Virtual functions may facilitate data abstraction in a more traditional
"Liskovian" sense, but run-time type dispatching deserves consideration
independent of OO's prejudices.

-thant


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Aaron Bentley
Guest





PostPosted: Wed Oct 22, 2003 6:30 pm    Post subject: Re: RTTI v.s. Liskov Principle Reply with quote

Matthias Hofmann wrote:
Quote:
Aaron Bentley <aaron.bentley (AT) utoronto (DOT) ca> schrieb in im Newsbeitrag:
ueykb.64$aw5.17248 (AT) news20 (DOT) bellglobal.com...

Shane Beasley wrote:

Aaron Bentley <aaron.bentley (AT) utoronto (DOT) ca> wrote in message

news:<WsQjb.5940$Z_2.467032 (AT) news20 (DOT) bellglobal.com>...

Obviously the point of polymorphism is that the behaviour will

change.

Ah, but that's not the point at all. :)

As per the C++ FAQ[1], subtype polymorphism is about allowing old code
to call new code. Old code specifies behavior; new code specifies only
how it will implement that behavior. If the new code behaves
differently than the old code expects, the protocol breaks down.

The bit about old code specifying behaviour is not in the FAQ, and I
disagree with it. The old code specifies operations that the new code
must support, but doesn't prescribe what those operations should do.



To be more precise, the old code does not prescribe what should happen
"under the hood", it only prescribes what should "appear" to happen. In
other words, it expects a certain input to lead to a certain result, no
matter what algorithm the new code choses.

So, for example you could have BubbleSorter::doSort(...) and
QuickSorter::doSort() be implemtations of the same virtual function.

They have the same inputs and outputs, but are implemented differently.

The only problem with that is that Quick Sort is a superior algorithm,
and while you might use BubbleSorter for debugging, there are very few
situations where you want to write a program that chooses the sorting
algorithm at runtime.

On the other hand, Square::draw() and Circle::draw() can be
implementations of the same virtual function (say
DrawableObject::draw()), and there are plenty of situations where you
want to draw a collection of DrawableObjects. But this use of
polymorphism is not included in your definition, because the differences
are not under the hood.

Quote:
If there is no difference in interface or behaviour betweeen two
classes, then why have two classes?



Because the same behaviour can be accomplished in different ways. The two
classes chose different ways.

If there's no observable difference, you should pick the superiour class
and just use that. Having two codepaths that do the same thing just
doubles your work for no appreciable gain.

Aaron

--
Aaron Bentley
www.aaronbentley.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Matthias Hofmann
Guest





PostPosted: Wed Oct 22, 2003 6:34 pm    Post subject: Re: RTTI v.s. Liskov Principle Reply with quote


Thant Tessman <thant (AT) acm (DOT) org> schrieb in im Newsbeitrag:
bn3u7s$pvr$1 (AT) terabinaries (DOT) xmission.com...
Quote:
Matthias Hofmann wrote:
Aaron Bentley <aaron.bentley (AT) utoronto (DOT) ca> schrieb in im Newsbeitrag:
ueykb.64$aw5.17248 (AT) news20 (DOT) bellglobal.com...


[...]

If there is no difference in interface or behaviour betweeen two
classes, then why have two classes?


Because the same behaviour can be accomplished in different ways. The
two classes chose different ways.

Consider the pedagogically ubiquitous Shape class with a virtual
function "draw" supplied by the sibling descendents Circle and Square.
You may want to argue that each sibling is distinguised not by behavior,
but by implementation. However, it seems more reasonable to think of
each as as implementing different behaviors invoked by a single but
context-sensitive message "draw."

One major issue of this discussion seems to be what "behaviour" actually
means. In your example, one might say that Circle and Square differ in
behaviour as the output is different. On the other hand, their behaviour is
*conceptually* identical as they do the same thing - draw their outline on
the screen.

Let's take another example: A class "AudioFile" with a virtual function
"Play()", which is supplied by the sibblings WavFile and Mp3File. Obviously,
the algorithm for playing a wave file is different from the algorithm that
plays an mp3 file. However, you won't notice a difference in behaviour when
you use these classes (assuming you can't hear the difference in sound
quality). This, I think, is an even better example for old code specifying
behaviour of new code. But the Shape example also works to express the idea,
as printing a different shape probably won't break the old code.

Quote:

Virtual functions may facilitate data abstraction in a more traditional
"Liskovian" sense, but run-time type dispatching deserves consideration
independent of OO's prejudices.


Of course it is possible to implement a virtual function "draw" that
actually erases your hard disk. As usual, nobody keeps you from shooting
yourself in the foot if you really want to. I wonder what Liskov means by
"changing the behaviour of the programm".

As for the original post: I think that RTTI does not violate the LSP as it
says nothing about the code *knowing* the real type of an object.

Regards,

Matthias




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.