473,387 Members | 1,791 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

"All public methods should be virtual" - yes or no / pros & cons

I'm on a team building some class libraries to be used by many other
projects.

Some members of our team insist that "All public methods should be virtual"
just in case "anything needs to be changed". This is very much against my
instincts. Can anyone offer some solid design guidelines for me?

Thanks in advance....
Nov 15 '05
175 8610
Martin Maat [EBL] <du***@somewhere.nl> wrote:
Yes, I understand, but I expect the GC to not bluntly collect garbage until
there's no more garbage to be found with its own thread set to time
critical. I expect it to take caution that it will not be in the apps way by
doing as much as it possibly can in idle time and by, if it really needs to
interfere, collecting some garbage for a minimum period of time and then
return control.


No, that's not what happens.

Just for a bit of fun, I wrote a little program to give the GC some
exercise. It's not actually terribly hard work for the GC, as there
aren't many traversals to do - just a single big array with some
elements in, which sometimes get overridden leaving garbage around. The
program keeps track of the longest amount of time it's taken to
allocate a new byte array. Here it is:

using System;

public class Test
{
static void Main()
{
TimeSpan maxTime = new TimeSpan();
byte[][] array = new byte[100000][];
Random r = new Random();

for (int i=0; i < 100000000; i++)
{
int index = r.Next(array.Length);
int size = r.Next (1000);
DateTime start = DateTime.Now;
array[index] = new byte[size];
DateTime end = DateTime.Now;
TimeSpan time = end-start;
if (time > maxTime)
{
maxTime = time;
Console.WriteLine (time.TotalMilliseconds);
}
}
}
}

It *rapidly* goes over 200ms on my laptop (which is a fairly nippy
box).

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #151
On Sun, 1 Feb 2004 02:53:28 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:

<snip>
The point I'm trying to make is you *CANNOT* override a method without
changing behaviour, so your second point is moot, it is simply a more
specific version of the first. Overriding is a behaviour change, be it at
the method level, the class level, or the system level. Even if your method
looks like
public override void MyMethod()
{
base.MyMethod();
}

I would still argue that it changes the behaviour of the class, although not
significantly.


<snip>

How?

Aside from rather mundane things like a few spare clock cycles to
perform the extra method call, if a client/calling method cannot
tell, from the *result* of invoking the overriden method, that the
method was, in fact, overriden, exactly in what way has the
/behaviour/ been changed?

Oz
Nov 15 '05 #152
Daniel O'Connell [C# MVP] <onyxkirx@--NOSPAM--comcast.net> wrote:
[...]
In everything but an idealized world, an override should be automatically
considered a change in behaviour. [...]
I'd go further: There is no reason one
would want to override a virtual function
except if one wants to change behaviour.
(Mhmm. OK, if you want to be nitpicking,
the case of overriding pure virtuals
remains to be discussed.)
[...]


Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers
Nov 15 '05 #153
ozbear <oz*****@yahoo.com> wrote:
On Sun, 1 Feb 2004 02:53:28 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:
[...] Even if your method
looks like
public override void MyMethod()
{
base.MyMethod();
}

I would still argue that it changes the behaviour of the class, although not
significantly.
<snip>

How?

Aside from rather mundane things like a few spare clock cycles to
perform the extra method call, if a client/calling method cannot
tell, from the *result* of invoking the overriden method, that the
method was, in fact, overriden, exactly in what way has the
/behaviour/ been changed?


Don't you consider performance to be
observable behaviour? I find it rather
easy to imagine a case where the above
change could render a whole app useless
due to the performance loss. And while
I can't imagine it, my experience with
that Murphy guy insists that this can
indeed happen where I'm sure it never
would. And I learned to trust this
Murphy experience over the years more
than my own judgements. :)
Oz


Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers
Nov 15 '05 #154
Bret Pehrson <br**@infowest.com> wrote:
[...]
Please elaborate on why you think this changes class behavior. I'll probably
learn something.
Daniel already tried to explain this.
I expect to read your headers, see and
recognize common patterns, understand
your identifiers, and use this interface
as it is with as little need for looking
it up in the docs as possible. If you
don't provide that, then that's one darn
good reason to look for another provider.


I'm not following. Maybe my statements weren't clear, but my intention is
this: any well-meaning programmer that produces code potentially for anyone
else (either directly or indirectly), should include complete and correct
documentation.


Of course. However, if my IDE tells me that
the function whos name I'm just typing is
virtual, I expect the class it belongs to
to be designed so that this function can be
overridden, because that's what virtual
functions are for. If I would find out
through the documentation, that this isn't
true, I would push really hard that we throw
the damn thing out the window and get a more
sensible designed lib.
It is extremely difficult (at best) to determine expected behavior from
prototypes and definitions alone (meaning, no documentation, *NO* comments).
If *you* can take naked prototypes and definitions and understand the usage,
behavior, and characteristics of the interface, then you are in a definite
minority. Personally, I rely heavily on the documentation.
Let's see... I just now have time to read
(and post in) this ng since I have changed
a header and need to re-build. I am working
at a kind of universal config file reader
that you can register functions with which
will get called when specific strings are
found in a config file. What I just did was
to add this function:

void readConfigFile(std::istream& is);

Would you look up the docs on this?
And what if I tell you that what actually I
inserted into the header is this

/*! \brief This reads a config file and calls the appropriate
** functions with the converted arguments for each
** feature string found
** \param is <==> config file to read
*/
void readConfigFile(std::istream& is);

Would you still want to look it up??

And now suppose, this function would do
everything as described, but pass the
arguments for the functins it is supposed
to call in the wrong order. Would you
still insist that, if the docs tell so,
that would be fine???

No no.
I expect to read your headers, see and
recognize common patterns, understand
your identifiers, and use this interface
as it is with as little need for looking
it up in the docs as possible. [...]
This still holds.
[...]


Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers
Nov 15 '05 #155
Bret Pehrson <br**@infowest.com> wrote:
Ah, "I am ignorant so you can't touch me".
Try re-reading. My original point was that you can't assume anything about
performance, because it is strictly tied to the implementation (and underlying
hardware).


You can assume that non-functions will
most likely have less, and never will
have more overhead than virtual functions.
I have yet to read *anything* in either the C or C++ spec that deals w/
performance. The thread is about the positives and negatives of MI, not
implementation-specific or performance.
> The only reason to make a function virtual is to allow it to be
> overridden. Overriding a function is changing behaviour.
Not true.


And then you provide an example demonstrating just what you are denying.


Nay, my good friend. My example does NOT change the behavior of the
**CLASS**. Perhaps you would care to elaborate as to why you think it does...


Suddenly your class causes a log file
to be written. Or another entry into
the log system. Or the trace might fail
and throw. Or...
Documentation should be the second line of support. Your code is the first.


You code is the first line if you are working *in the code*. Although not
explicitly defined as such, this thread has been primarily limited to the
presumption that only the interface is avaialble (i.e. header files). My
documentation comments are based on that.


I think Martin meant this. Declarations
_are_ code, after all.
[...]
Excluding the 'dreaded diamond' issue of MI, can someone substantively say why
MI should *NOT* be part of a language???
I couldn't. But then I hadn't read anything
against MI in this thread.
[...]


Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers
Nov 15 '05 #156
.. <.> wrote:
[...]
Ofcourse C++ is still used but watch C# take the mainstream applications and
C++ for specific interop and time / memory critical applications. [...]

There is more to this. A lot, actually.

There is billions of lines of C/C++ code
out there that nobody will rewrite in C#
(or whatever the mainstreamers consider
today's mainstream language). This not
only needs to compile, it also needs to
get fixed and extended.
There is billions of line of C/C++ code
that is (also) compiled and used on other
platforms than Windows. C# doesn't help
with these at all. While Windows (and thus
maybe .NET someday) might be the main
platform that you and I use, that doesn't
mean it is all there is.

The shop I work for has a lot of code that
runs on Win9X, NT, 2k, XP, MacOS Classic,
MacOSX, Linux, and BSD, using half a dozen
C++ compiler/std lib compinations. And a
lot of it runs either as plugin for various
applications or as a standalone app. There
is no critical performance contraints on
our apps (other than the usual "the faster,
the less the users have to wait"). Still --
.NET and C# are out of question.

Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers
Nov 15 '05 #157
Not sure why you think the GC has no hard time running this code?
With this allocation scheme, very quickly, millions of objects (all < 1000
bytes) tend to survive into gen2.
The result is that, once the gen2 threshold has been reached, the GC kicks
in for a full collect, resulting in a relocation of several tens of
megabytes, which is extremely expensive especially when the garbage is
located near the start of the GC2 heap.

Willy.
relocating
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Martin Maat [EBL] <du***@somewhere.nl> wrote:
Yes, I understand, but I expect the GC to not bluntly collect garbage
until
there's no more garbage to be found with its own thread set to time
critical. I expect it to take caution that it will not be in the apps way
by
doing as much as it possibly can in idle time and by, if it really needs
to
interfere, collecting some garbage for a minimum period of time and then
return control.


No, that's not what happens.

Just for a bit of fun, I wrote a little program to give the GC some
exercise. It's not actually terribly hard work for the GC, as there
aren't many traversals to do - just a single big array with some
elements in, which sometimes get overridden leaving garbage around. The
program keeps track of the longest amount of time it's taken to
allocate a new byte array. Here it is:

using System;

public class Test
{
static void Main()
{
TimeSpan maxTime = new TimeSpan();
byte[][] array = new byte[100000][];
Random r = new Random();

for (int i=0; i < 100000000; i++)
{
int index = r.Next(array.Length);
int size = r.Next (1000);
DateTime start = DateTime.Now;
array[index] = new byte[size];
DateTime end = DateTime.Now;
TimeSpan time = end-start;
if (time > maxTime)
{
maxTime = time;
Console.WriteLine (time.TotalMilliseconds);
}
}
}
}

It *rapidly* goes over 200ms on my laptop (which is a fairly nippy
box).

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 15 '05 #158
"Martin Maat [EBL]" <du***@somewhere.nl> wrote in message
[snip]
I don't think so. To do a collection in a uniprocessor system the GC has to
suspend *all* threads that are currently running managed code.


Yes, I understand, but I expect the GC to not bluntly collect garbage until
there's no more garbage to be found with its own thread set to time
critical.
I expect it to take caution that it will not be in the apps way by
doing as much as it possibly can in idle time and by,


Even if you detect that the program is not currently consuming many
cycles it might do so just a millisecond later. Once a collection is
started it cannot be interrupted because doing so would leave you with
absolutely no garbage collected. Since you were not able to visit all
objects you cannot possibly tell whether anything truly is garbage or
not.
Therefore, the GC has no other choice but to kick in when it feels it
must and then collect *all* the garbage in the generation.
if it really needs to
interfere, collecting some garbage for a minimum period of time and then
return control. The aggression applied is likely to be proportional to the
need. If I (the application programmer) were to generate garbage
relentlessly, the GC will probably start fighting me for processing time at
some point. While I am being a good boy however, not giving it a reason to
pull my leash, I expect it to be very very gentle with me, only collecting
garbage for very short periods.


To some extent the .NET GC does exactly this, by doing faster lower
order generation collections much more often than slower higher order
ones. However, when it comes to hard realtime systems you have to
design your system so that it can deal with the worst case, i.e. a
full gen 2 collection *any time*. If such a collection can take
seconds as remarked by Justin Rogers, then it is suicide to use .NET
for just about any hard realtime application.

Regards,

Andreas
Nov 15 '05 #159
Willy Denoyette [MVP] <wi*************@pandora.be> wrote:
Not sure why you think the GC has no hard time running this code?
With this allocation scheme, very quickly, millions of objects (all < 1000
bytes) tend to survive into gen2.
Yup.
The result is that, once the gen2 threshold has been reached, the GC kicks
in for a full collect, resulting in a relocation of several tens of
megabytes, which is extremely expensive especially when the garbage is
located near the start of the GC2 heap.


Yes, it was deliberately designed to get as many objects as possible
into generation 2, but in other ways it's very simple - each object
that it looks at is independent, other than the "overarching" array. In
other words, the hierarchy itself is very simple - it's very wide, but
very shallow. That was the easiest way I could figure out of exercising
the garbage collector without too many lines of code. If that hadn't
confused it enough I'd have tried harder, but as my first attempt went
over the 200ms threshold, I thought I'd leave it there :)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 15 '05 #160
> Don't you consider performance to be
observable behaviour?
Performance is a *characteristic*, not a behavior.

For the life of me, I can't figure out why no one seems to be able to
understand that there is more than one reason (change of behavior) for virtual
methods.
Hendrik Schober wrote:
ozbear <oz*****@yahoo.com> wrote:
On Sun, 1 Feb 2004 02:53:28 -0600, "Daniel O'Connell [C# MVP]"
<onyxkirx@--NOSPAM--comcast.net> wrote:
[...] Even if your method
looks like
public override void MyMethod()
{
base.MyMethod();
}

I would still argue that it changes the behaviour of the class, although not
significantly.


<snip>

How?

Aside from rather mundane things like a few spare clock cycles to
perform the extra method call, if a client/calling method cannot
tell, from the *result* of invoking the overriden method, that the
method was, in fact, overriden, exactly in what way has the
/behaviour/ been changed?


Don't you consider performance to be
observable behaviour? I find it rather
easy to imagine a case where the above
change could render a whole app useless
due to the performance loss. And while
I can't imagine it, my experience with
that Murphy guy insists that this can
indeed happen where I'm sure it never
would. And I learned to trust this
Murphy experience over the years more
than my own judgements. :)
Oz


Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers


--
Bret Pehrson
mailto:br**@infowest.com
NOSPAM - Include this key in all e-mail correspondence <<38952rglkwdsl>>
Nov 15 '05 #161
> I'd go further: There is no reason one
would want to override a virtual function
except if one wants to change behaviour.
Please revise your statement. It should read:

There is no reason YOU would want to override ... except to change behaviour.

As I've explained several times, there *ARE* other reasons to override aside
from changing behavior. Those reasons are real and valid.
Hendrik Schober wrote:
Daniel O'Connell [C# MVP] <onyxkirx@--NOSPAM--comcast.net> wrote:
[...]
In everything but an idealized world, an override should be automatically
considered a change in behaviour. [...]


I'd go further: There is no reason one
would want to override a virtual function
except if one wants to change behaviour.
(Mhmm. OK, if you want to be nitpicking,
the case of overriding pure virtuals
remains to be discussed.)
[...]


Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers


--
Bret Pehrson
mailto:br**@infowest.com
NOSPAM - Include this key in all e-mail correspondence <<38952rglkwdsl>>
Nov 15 '05 #162
> the method level, the class level, or the system level. Even if your method
looks like
public override void MyMethod()
{
base.MyMethod();
}

I would still argue that it changes the behaviour of the class, although not
significantly.
I'm still waiting to hear a (substantive) reason why this changes behavior. So
far I haven't ...
"Daniel O'Connell [C# MVP]" wrote:
"Bret Pehrson" <br**@infowest.com> wrote in message
news:40***************@infowest.com...
In everything but an idealized world, an override should be automatically considered a change in behaviour.


You have missed my point completely. I'll summarize (again), and then I'm
done.

There is more than one reason to create virtual methods:

1 - to allow a subsequent user to change behavior

2 - to allow a subsequent user to track/monitor methods or state data

*without*
modifying behavior


The point I'm trying to make is you *CANNOT* override a method without
changing behaviour, so your second point is moot, it is simply a more
specific version of the first. Overriding is a behaviour change, be it at
the method level, the class level, or the system level. Even if your method
looks like
public override void MyMethod()
{
base.MyMethod();
}

I would still argue that it changes the behaviour of the class, although not
significantly. I know what you intended to point out, I simply believe its a
false premise. If you write code with ramifications you are writing code
that changes behaviour, period(in effect, that reduces to "If you write
code, you are changing behaviour"). I simply find it silly and potentially
dangerous to decide otherwise.
There are probably other reasons as well...

Forget the example, it was merely to illustrate my point #2 above, NOT to

be a
point of endless debate on what possible ramifications trace() has on the
system, etc. ad naseum.

"Daniel O'Connell [C# MVP]" wrote:

"Bret Pehrson" <br**@infowest.com> wrote in message
news:40***************@infowest.com...
> > Simple, you do *anything* and what your class does changes.
>
> No, no, NO!
>
> Come on, my example doesn't change the behaior of the class -- period. It may
> (and very well does) change the state or behavior of the *SYSTEM*, but we are
> *not* talking about that.
If your method changes the system, then the behaviour of your class now
includes that change to the system, a classes behaviour is *EVERYTHING*, not just the class state. Even if it doesn't change the result of the call it still changes behaviour(and even in your example it *could* change the
result of the call by throwing an exception). Its likely behaviour you
*must* document, and treat as a behaviour change.

Of course, if you don't consider adding the chance of new exceptions, new ways to fail, or new possible constraints on parameters a change in
behaviour, I think our definitions of the word differ.

In everything but an idealized world, an override should be automatically considered a change in behaviour. Even if you can guarentee ironclad that it works without any behaviour change, you still leave the chance that a change *elsewhere* could change behaviour elsewhere(which is part of the problem, a code change *anywhere* is a change in behaviour, potentially in the entire system, even if its not entirely noticable or anything that actually effects change).
>
> The point was, is, and will continue to be: virtual methods can be used to
> change behavior ***OR*** for other reasons that *DO NOT CHANGE BEHAVIOR*, which
> is what I've illustrated.
>
> "Daniel O'Connell [C# MVP]" wrote:
> >
> > "Bret Pehrson" <br**@infowest.com> wrote in message
> > news:40***************@infowest.com...
> > > > This does change behaviour. (And I don't
> > > > think I want/need to tell you how.)
> > >
> > > Then don't post a response! We are (presumably) all here for
constructive
> > and
> > > educational reasons, so you statement provides nothing and actually > > confuses
> > > the issue.
> > >
> > > Please elaborate on why you think this changes class behavior. I'll > > probably
> > > learn something.
> > Simple, you do *anything* and what your class does changes. If that call > > throws an exception you are adding a point of failure, if that call
> > instantiates objects you are using memory(and perhaps creating a memory > > leak), if that call deletes random files you are probably angering
users, if
> > that call changes an object or variable the underlying method uses in > > another class you could introduce unexpected bugs and it all may rain down
> > on someone elses head because of it. Simply because your call leaves the > > instance alone does *NOT* mean that its behaviour isn't changed, its
state
> > simply isn't. Behaviour is considerably more than simply what Method A does
> > to Field B. Your example likely doesn't change the object but
potentially
> > changes the entire universe the object exists in.
> > >
> > > > I expect to read your headers, see and
> > > > recognize common patterns, understand
> > > > your identifiers, and use this interface
> > > > as it is with as little need for looking
> > > > it up in the docs as possible. If you
> > > > don't provide that, then that's one darn
> > > > good reason to look for another provider.
> > >
> > > I'm not following. Maybe my statements weren't clear, but my
intention is
> > > this: any well-meaning programmer that produces code potentially for > > anyone
> > > else (either directly or indirectly), should include complete and
correct
> > > documentation.
> > >
> > > It is extremely difficult (at best) to determine expected behavior
from
> > > prototypes and definitions alone (meaning, no documentation, *NO*
> > comments).
> > > If *you* can take naked prototypes and definitions and understand the > > usage,
> > > behavior, and characteristics of the interface, then you are in a
definite
> > > minority. Personally, I rely heavily on the documentation.
> > >
> > > Hendrik Schober wrote:
> > > >
> > > > Bret Pehrson <br**@infowest.com> wrote:
> > > > > [...]
> > > > > > The only reason to make a function virtual
> > > > > > is to allw it to be overridden. Overriding
> > > > > > a function is changing behaviour.
> > > > >
> > > > > Not true.
> > > > >
> > > > > class A
> > > > > {
> > > > > public:
> > > > > virtual void a()
> > > > > {
> > > > > // do something
> > > > > }
> > > > > };
> > > > >
> > > > > class B : public A
> > > > > {
> > > > > public:
> > > > > virtual void a()
> > > > > {
> > > > > A::a();
> > > > > trace("processing a");
> > > > > }
> > > > > }
> > > > >
> > > > > This doesn't change behavior, but is a very valid and real-world case
> > of
> > > > > virtual overrides.
> > > >
> > > > This does change behaviour. (And I don't
> > > > think I want/need to tell you how.)
> > > >
> > > > > > Don't expect us to carefully read douments
> > > > > > that contradict your code.
> > > > >
> > > > > ???
> > > > >
> > > > > I do expect you to carefully read documents that define the
behavior,
> > usage,
> > > > > and intent of my interfaces.
> > > >
> > > > I expect to read your headers, see and
> > > > recognize common patterns, understand
> > > > your identifiers, and use this interface
> > > > as it is with as little need for looking
> > > > it up in the docs as possible. If you
> > > > don't provide that, then that's one darn
> > > > good reason to look for another provider.
> > > >
> > > > > [...]
> > > >
> > > > Schobi
> > > >
> > > > --
> > > > Sp******@gmx.de is never read
> > > > I'm Schobi at suespammers dot org
> > > >
> > > > "Sometimes compilers are so much more reasonable than people."
> > > > Scott Meyers
> > >
> > > --
> > > Bret Pehrson
> > > mailto:br**@infowest.com
> > > NOSPAM - Include this key in all e-mail correspondence
<<38952rglkwdsl>>
>
> --
> Bret Pehrson
> mailto:br**@infowest.com
> NOSPAM - Include this key in all e-mail correspondence

<<38952rglkwdsl>>

--
Bret Pehrson
mailto:br**@infowest.com
NOSPAM - Include this key in all e-mail correspondence <<38952rglkwdsl>>


--
Bret Pehrson
mailto:br**@infowest.com
NOSPAM - Include this key in all e-mail correspondence <<38952rglkwdsl>>
Nov 15 '05 #163
Bret Pehrson <br**@infowest.com> wrote:
Don't you consider performance to be
observable behaviour?
Performance is a *characteristic*, not a behavior.


If your program misses data on a serial
port due to this, it changes behaviour.
So a performance change _is_ a behaviour
change.
For the life of me, I can't figure out why no one seems to be able to
understand that there is more than one reason (change of behavior) for virtual
methods.
Probably because there isn't?
[...]

Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers
Nov 15 '05 #164
Dude, you need to stop being so explicit w/ this topic.

Here is another example, where behavior is NOT changed:

class A
{
protected:
virtual void OnStartup() { }
};

class B : public A
{
protected:
virtual void OnStartup() {
log_event_no_exceptions_or_performance_penalties() ; }
};

Now, if you would just look at this as the *INTENT* to not modify behavior, but
to monitor events, you now have, get this, another reason for virtual methods.

Let me revise my original statement (way back when):

Overriding serves multiple purposes:

- the INTENT to modify behavior

- the INTENT to monitor events (without the INTENT to modify behavior)

- probably other reasons

Is there anyone else out there reading this thread that agrees w/ me???
Hendrik Schober wrote:

Bret Pehrson <br**@infowest.com> wrote:
Don't you consider performance to be
observable behaviour?


Performance is a *characteristic*, not a behavior.


If your program misses data on a serial
port due to this, it changes behaviour.
So a performance change _is_ a behaviour
change.
For the life of me, I can't figure out why no one seems to be able to
understand that there is more than one reason (change of behavior) for virtual
methods.


Probably because there isn't?
[...]


Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers


--
Bret Pehrson
mailto:br**@infowest.com
NOSPAM - Include this key in all e-mail correspondence <<38952rglkwdsl>>
Nov 15 '05 #165
But you have modified behaviour, you have it monitoring of events now. Thats
a modification.
"Bret Pehrson" <br**@infowest.com> wrote in message
news:40***************@infowest.com...
Dude, you need to stop being so explicit w/ this topic.

Here is another example, where behavior is NOT changed:

class A
{
protected:
virtual void OnStartup() { }
};

class B : public A
{
protected:
virtual void OnStartup() {
log_event_no_exceptions_or_performance_penalties() ; }
};

Now, if you would just look at this as the *INTENT* to not modify behavior, but to monitor events, you now have, get this, another reason for virtual methods.
Let me revise my original statement (way back when):

Overriding serves multiple purposes:

- the INTENT to modify behavior

- the INTENT to monitor events (without the INTENT to modify behavior)

- probably other reasons

Is there anyone else out there reading this thread that agrees w/ me???
Hendrik Schober wrote:

Bret Pehrson <br**@infowest.com> wrote:
> Don't you consider performance to be
> observable behaviour?

Performance is a *characteristic*, not a behavior.


If your program misses data on a serial
port due to this, it changes behaviour.
So a performance change _is_ a behaviour
change.
For the life of me, I can't figure out why no one seems to be able to
understand that there is more than one reason (change of behavior) for virtual methods.


Probably because there isn't?
[...]


Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers


--
Bret Pehrson
mailto:br**@infowest.com
NOSPAM - Include this key in all e-mail correspondence <<38952rglkwdsl>>

Nov 15 '05 #166
Sorry, you are wrong. It is not an intent to modify behavior.

Still 2 reasons for virtual methods, anyone want to break into the limelight
and offer a third?

.. wrote:

But you have modified behaviour, you have it monitoring of events now. Thats
a modification.

"Bret Pehrson" <br**@infowest.com> wrote in message
news:40***************@infowest.com...
Dude, you need to stop being so explicit w/ this topic.

Here is another example, where behavior is NOT changed:

class A
{
protected:
virtual void OnStartup() { }
};

class B : public A
{
protected:
virtual void OnStartup() {
log_event_no_exceptions_or_performance_penalties() ; }
};

Now, if you would just look at this as the *INTENT* to not modify

behavior, but
to monitor events, you now have, get this, another reason for virtual

methods.

Let me revise my original statement (way back when):

Overriding serves multiple purposes:

- the INTENT to modify behavior

- the INTENT to monitor events (without the INTENT to modify behavior)

- probably other reasons

Is there anyone else out there reading this thread that agrees w/ me???
Hendrik Schober wrote:

Bret Pehrson <br**@infowest.com> wrote:
> > Don't you consider performance to be
> > observable behaviour?
>
> Performance is a *characteristic*, not a behavior.

If your program misses data on a serial
port due to this, it changes behaviour.
So a performance change _is_ a behaviour
change.

> For the life of me, I can't figure out why no one seems to be able to
> understand that there is more than one reason (change of behavior) for virtual > methods.

Probably because there isn't?

> [...]

Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers


--
Bret Pehrson
mailto:br**@infowest.com
NOSPAM - Include this key in all e-mail correspondence <<38952rglkwdsl>>


--
Bret Pehrson
mailto:br**@infowest.com
NOSPAM - Include this key in all e-mail correspondence <<38952rglkwdsl>>
Nov 15 '05 #167
Bret Pehrson <br**@infowest.com> wrote:
Dude, you need to stop being so explicit w/ this topic.

Here is another example, where behavior is NOT changed:

class A
{
protected:
virtual void OnStartup() { }
};

class B : public A
{
protected:
virtual void OnStartup() {
log_event_no_exceptions_or_performance_penalties() ; }
};

Now, if you would just look at this as the *INTENT* to not modify behavior, but
to monitor events, you now have, get this, another reason for virtual methods.
The 'B' is logging, 'A' isn't. It might be
me beeing a non-native speaker, but therefor
I would say 'B' behaves different than 'A'
does.
(And it seems hard to argue that this was
not intended, since the programmer did call
the function explicitly and I don't see any
reason for the derivation/overriding other
than to log the event.)

Also, as it was already expressed that even
calling a function that does nothing is
considered a change of behaviour, I don't
see what your point is with the above example.
[...]


Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers
Nov 15 '05 #168
Bret Pehrson <br**@infowest.com> wrote:
Sorry, you are wrong.
Dot gave a reason for his/her statement,
you didn't. You won't making this any
more true by simply reapeating it.
It is not an intent to modify behavior.
Nobody doubts this. Yet it is modified.
Still 2 reasons for virtual methods, anyone want to break into the limelight
and offer a third?
I guess I'll quit this discussion now.
We have all repeated the same arguments
over and over, and you keep saying we
are wrong without making a point why
that would be so.
[...]


Schobi

--
Sp******@gmx.de is never read
I'm Schobi at suespammers dot org

"Sometimes compilers are so much more reasonable than people."
Scott Meyers
Nov 15 '05 #169
There maybe no INTENT but you sure did modify it, B.OnStartup is no way the
same as A.OnStartup, it maybe similar but its not the same method.

If you see it as the same method where do you buy your glasses? The very
monitoring of events call is a modification. Check the IL its NOT the same.

"Bret Pehrson" <br**@infowest.com> wrote in message
news:40***************@infowest.com...
Sorry, you are wrong. It is not an intent to modify behavior.

Still 2 reasons for virtual methods, anyone want to break into the limelight and offer a third?

. wrote:

But you have modified behaviour, you have it monitoring of events now. Thats a modification.

"Bret Pehrson" <br**@infowest.com> wrote in message
news:40***************@infowest.com...
Dude, you need to stop being so explicit w/ this topic.

Here is another example, where behavior is NOT changed:

class A
{
protected:
virtual void OnStartup() { }
};

class B : public A
{
protected:
virtual void OnStartup() {
log_event_no_exceptions_or_performance_penalties() ; }
};

Now, if you would just look at this as the *INTENT* to not modify behavior, but
to monitor events, you now have, get this, another reason for virtual

methods.

Let me revise my original statement (way back when):

Overriding serves multiple purposes:

- the INTENT to modify behavior

- the INTENT to monitor events (without the INTENT to modify behavior)
- probably other reasons

Is there anyone else out there reading this thread that agrees w/ me???

Hendrik Schober wrote:
>
> Bret Pehrson <br**@infowest.com> wrote:
> > > Don't you consider performance to be
> > > observable behaviour?
> >
> > Performance is a *characteristic*, not a behavior.
>
> If your program misses data on a serial
> port due to this, it changes behaviour.
> So a performance change _is_ a behaviour
> change.
>
> > For the life of me, I can't figure out why no one seems to be able to > > understand that there is more than one reason (change of behavior)
for virtual
> > methods.
>
> Probably because there isn't?
>
> > [...]
>
> Schobi
>
> --
> Sp******@gmx.de is never read
> I'm Schobi at suespammers dot org
>
> "Sometimes compilers are so much more reasonable than people."
> Scott Meyers

--
Bret Pehrson
mailto:br**@infowest.com
NOSPAM - Include this key in all e-mail correspondence

<<38952rglkwdsl>>
--
Bret Pehrson
mailto:br**@infowest.com
NOSPAM - Include this key in all e-mail correspondence <<38952rglkwdsl>>

Nov 15 '05 #170
I don't care about the IL -- I'm talking about design. I can't get much more
plain than what I've already said.

So, it still stands, there are 2 reasons for virtual methods.

.. wrote:

There maybe no INTENT but you sure did modify it, B.OnStartup is no way the
same as A.OnStartup, it maybe similar but its not the same method.

If you see it as the same method where do you buy your glasses? The very
monitoring of events call is a modification. Check the IL its NOT the same.

"Bret Pehrson" <br**@infowest.com> wrote in message
news:40***************@infowest.com...
Sorry, you are wrong. It is not an intent to modify behavior.

Still 2 reasons for virtual methods, anyone want to break into the

limelight
and offer a third?

. wrote:

But you have modified behaviour, you have it monitoring of events now. Thats a modification.

"Bret Pehrson" <br**@infowest.com> wrote in message
news:40***************@infowest.com...
> Dude, you need to stop being so explicit w/ this topic.
>
> Here is another example, where behavior is NOT changed:
>
> class A
> {
> protected:
> virtual void OnStartup() { }
> };
>
> class B : public A
> {
> protected:
> virtual void OnStartup() {
> log_event_no_exceptions_or_performance_penalties() ; }
> };
>
> Now, if you would just look at this as the *INTENT* to not modify
behavior, but
> to monitor events, you now have, get this, another reason for virtual
methods.
>
> Let me revise my original statement (way back when):
>
> Overriding serves multiple purposes:
>
> - the INTENT to modify behavior
>
> - the INTENT to monitor events (without the INTENT to modify behavior) >
> - probably other reasons
>
> Is there anyone else out there reading this thread that agrees w/ me??? >
>
> Hendrik Schober wrote:
> >
> > Bret Pehrson <br**@infowest.com> wrote:
> > > > Don't you consider performance to be
> > > > observable behaviour?
> > >
> > > Performance is a *characteristic*, not a behavior.
> >
> > If your program misses data on a serial
> > port due to this, it changes behaviour.
> > So a performance change _is_ a behaviour
> > change.
> >
> > > For the life of me, I can't figure out why no one seems to be able to > > > understand that there is more than one reason (change of behavior) for virtual
> > > methods.
> >
> > Probably because there isn't?
> >
> > > [...]
> >
> > Schobi
> >
> > --
> > Sp******@gmx.de is never read
> > I'm Schobi at suespammers dot org
> >
> > "Sometimes compilers are so much more reasonable than people."
> > Scott Meyers
>
> --
> Bret Pehrson
> mailto:br**@infowest.com
> NOSPAM - Include this key in all e-mail correspondence

<<38952rglkwdsl>>

--
Bret Pehrson
mailto:br**@infowest.com
NOSPAM - Include this key in all e-mail correspondence <<38952rglkwdsl>>


--
Bret Pehrson
mailto:br**@infowest.com
NOSPAM - Include this key in all e-mail correspondence <<38952rglkwdsl>>
Nov 15 '05 #171
"Bret Pehrson" <br**@infowest.com> wrote in message
news:40***************@infowest.com...
I would still argue that it changes the behaviour of the class, although not significantly.
I'm still waiting to hear a (substantive) reason why this changes behavior. So far I haven't ...


Can we stop this now please? Bret is, although besides the point, basically
right discriminating between behavior and characteristics. If you are
thinking strictly OO though there's only data and behavior and any change to
a method is a change in behavior. The discussion is pointless, the initial
statement wasn't even focussing on behavior as such but rather on the
question whether it would be appropriate to use a virtual method (primarily
a means to express polymorphism) as a plug-in mechanism. Should we use it
for delegation or even event purposes that not necessarily change behavior
in a polymorphic or specializing sense?

If I walk up to my fridge one day to have breakfast and the next morning I
do the same but I limp because I hurt myself in the meantime, did my
behavior change? Technically, yes. Logically, no.

If you use a private method with the purpose of plugging in a log action you
are not changing your OO-model in the sense that you are not specializing
nor expanding your base type's behavior as far as its problem domain is
concerned nor are you creating a new incarnation of it. This is why I feel
it is in this case inappropriate to use a virtual method in the first place
because virtual methods are typically strongly associated with and meant to
be used for implementing the very features that do not apply in this case.

Anyway, you can all be right depending on the level onto which you want to
apply your statement about behavior. To technical level participants
behavior changes, to problem domain level participants behavior does not
necessarily change. No let's make up and start a more interesting issue to
disagree on.

Martin.
Nov 15 '05 #172

"Bret Pehrson" <br**@infowest.com> wrote in message
news:40***************@infowest.com...
I don't care about the IL -- I'm talking about design. I can't get much more plain than what I've already said.

So, it still stands, there are 2 reasons for virtual methods.


Noone doubt's that it's is possible to override a method without the
explicit intent to modify behavior. That doesn't change the fact that
overriding a method does change behavior.
I believe your mistake is confusing the return value, or stated purpose, of
a method with the entirety of the consequences of the implementation of the
method. In many cases the changes in behavior that your examples will cause
is irrelevant, but it's still there.

/Magnus Lidbom

Nov 15 '05 #173

"Martin Maat [EBL]" <du***@somewhere.nl> wrote in message
news:10*************@corp.supernews.com...
"Bret Pehrson" <br**@infowest.com> wrote in message
news:40***************@infowest.com...

If you use a private method with the purpose of plugging in a log action you are not changing your OO-model in the sense that you are not specializing
nor expanding your base type's behavior as far as its problem domain is
concerned nor are you creating a new incarnation of it. This is why I feel
it is in this case inappropriate to use a virtual method in the first place because virtual methods are typically strongly associated with and meant to be used for implementing the very features that do not apply in this case. Public virtuals, yes. Protected, no.
If something in the public interface of a class is virtual it's a statement
that the implementation of that member may be replaced. Using a protected
virtual to allow extentions of the sort discussed in this thread does not
modify the contract implicitly defined by a class's public interface. If you
have a reason why an implementaion like below would be inappropriate I'd
like to hear it:

class Base
{
public void DoStuff()
{
//Check invariants
//Do stuff:
ExtendDoStuff();
//Check invariants
}

protected virtual void ExtendDoStuff()
{
}
}

class Inhertiting : Base
{
protected override void ExtendDoStuff()
{
//Log something.
}
}

Anyway, you can all be right depending on the level onto which you want to
apply your statement about behavior. To technical level participants
behavior changes, to problem domain level participants behavior does not
necessarily change. No let's make up and start a more interesting issue to
disagree on.

How about the above? :)

/Magnus Lidbom


Nov 15 '05 #174
> If you have a reason why an implementaion like below would be
inappropriate I'd like to hear it: class Base
{
public void DoStuff()
{
//Check invariants
//Do stuff:
ExtendDoStuff();
//Check invariants
}

protected virtual void ExtendDoStuff()
{
}
}

class Inhertiting : Base
{
protected override void ExtendDoStuff()
{
//Log something.
}
}


Because you are basically implementing an event, not extending problem
domain behavior as the method's name suggests. So it would be more
appropriate to use an event, to implement some sort of callback in the base
class (C# delegate). Your example and all of the others provided earlier to
convince us that behavior is changed or behavior is not changed are using
inheritence for the wrong reasons.

It is purely academic of course but hey, that's what we're her for.

Martin.
Nov 15 '05 #175
If the team wants everything virtual, fc.uk em, what I do now is when people
are persistant, I just give them what they cry for, S.hite design
implementation. When the shit hits the fan , fingers get pointed :D If I
want something done a certain way, I do that at home.

If a company wants a s.hit product, I can equally give them that if they
p.iss me off.
"Martin Maat [EBL]" <du***@somewhere.nl> wrote in message
news:10*************@corp.supernews.com...
If you have a reason why an implementaion like below would be
inappropriate I'd like to hear it:
class Base
{
public void DoStuff()
{
//Check invariants
//Do stuff:
ExtendDoStuff();
//Check invariants
}

protected virtual void ExtendDoStuff()
{
}
}

class Inhertiting : Base
{
protected override void ExtendDoStuff()
{
//Log something.
}
}


Because you are basically implementing an event, not extending problem
domain behavior as the method's name suggests. So it would be more
appropriate to use an event, to implement some sort of callback in the

base class (C# delegate). Your example and all of the others provided earlier to convince us that behavior is changed or behavior is not changed are using
inheritence for the wrong reasons.

It is purely academic of course but hey, that's what we're her for.

Martin.

Nov 15 '05 #176

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

164
by: Ken Brady | last post by:
I'm on a team building some class libraries to be used by many other projects. Some members of our team insist that "All public methods should be virtual" just in case "anything needs to be...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.