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 

Re: Confused about non-virtual functions
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++)
View previous topic :: View next topic  
Author Message
Victor Bazarov
Guest





PostPosted: Tue Jun 24, 2003 1:04 am    Post subject: Re: Confused about non-virtual functions Reply with quote



"Robert William Vesterman" <bob (AT) vesterman (DOT) com> wrote...
Quote:
I'm confused about the purpose of non-virtual functions. As I
understand it, if you have a class E that extends a class B and
overrides a non-virtual function f(),

OK, here is your first mistake. If the function is non-virtual,
nothing can _override_ it. Any member of the derived class with
the same name _hides_ it.

Quote:
then the f() that actually gets
called for an E object depends upon whether that E object is known as
an E or as a B at the time of the call.

No. Any non-virtual function call is resolved at compile time.
If object of type E is passed where a reference, say, to B is
expected, no object E exists inside, only the B part of E is
passed in:

void foo(B& rb)
{
// Here there is no 'E'. There is only 'B'
rb.f();
}

void bar()
{
E e;
foo(e); // 'e' is converted to 'B&'.
}

Quote:
I don't understand what's useful about this ambiguity in what the f()
of an E is. Could someone please give me an example of why it would
be useful?

Non-static functions are bound (resolved) at compile time. It
speeds up the process (no need to look it up using sime kind of
virtual function mechanism), and absence of virtual functions
usually means smaller objects. Leaner, meaner.

Having a member function that has the same (or similar) type
in two classes can be a requirement from the design point of
view. Let's take a very simple example: to be able to sort
a collection of objects of type T using standard means, the T
needs to have operator < defined (if no special comparison
function is provided). To use two different classes (whether
related or not) in some generic algorithm that requires the use
of some function 'f()', the two classes have to both implement
that function. You may have only one version of it, in the
base class of the two, and let the derived one use it, or you
may need to redefine it just because it has to use some data
members in that class. The function doesn't have to be virtual
because due to the intention it will never be called through
polymorphic means.

Quote:
I don't mean "useful as opposed to virtual functions". I mean "useful
as opposed to not allowing non-virtual functions to be overridden in
the first place".

Non-virtual functions cannot be overridden. Please print that
statement out on a sheet of paper and hang above your monitor.

Quote:
That is, imagine a language C++--, which is identical to C++ except
that non-virtual functions cannot be overridden.

Why imagine anything? In C++ non-virtual functions cannot be
overridden.

Quote:
What's an example of
a case where C++ is more useful, or nicer, or cleaner, or safer, or
more whatever, than C++--?

Learn the language. It's useful, nice, clean, safe, as it is.

Victor



Back to top
David White
Guest





PostPosted: Tue Jun 24, 2003 1:06 am    Post subject: Re: Confused about non-virtual functions Reply with quote



Robert William Vesterman <bob (AT) vesterman (DOT) com> wrote

Quote:
I'm confused about the purpose of non-virtual functions. As I
understand it, if you have a class E that extends a class B and
overrides a non-virtual function f(), then the f() that actually gets
called for an E object depends upon whether that E object is known as
an E or as a B at the time of the call.

Here 'known as' means the declared type where the call is made, I take it.

Non-virtual functions are overwhelmingly those that are not overridden at
all. Their purpose is to do something that is not for overriding. Virtual
function calls require indirection, for which there is likely to be a
performance penalty, a penalty that is unnecessary if the function is not to
be overridden.

Quote:
I don't understand what's useful about this ambiguity in what the f()
of an E is. Could someone please give me an example of why it would
be useful?

I can't think of one. I can't think of a circumstance in which I would
override a non-virtual function.

Quote:
I don't mean "useful as opposed to virtual functions". I mean "useful
as opposed to not allowing non-virtual functions to be overridden in
the first place".

I would suggest that a compiler issue a warning, at least, whenever a
non-virtual function is overridden.

David




Back to top
Robert William Vesterman
Guest





PostPosted: Tue Jun 24, 2003 1:38 am    Post subject: Re: Confused about non-virtual functions Reply with quote



Great, great, great. Thank you for the semantics lesson. Please
allow me to rephrase my question:

Please give me an example of why it is useful that C++ allows the
following:

class Base
{
void func ( void );
};

class Derived : public Base
{
void func ( void );
};

Thank you.

Bob Vesterman.
Back to top
Victor Bazarov
Guest





PostPosted: Tue Jun 24, 2003 1:44 am    Post subject: Re: Confused about non-virtual functions Reply with quote

"Robert William Vesterman" <bob (AT) vesterman (DOT) com> wrote...
Quote:
Great, great, great. Thank you for the semantics lesson. Please
allow me to rephrase my question:

Please give me an example of why it is useful that C++ allows the
following:

class Base
{
void func ( void );
};

class Derived : public Base
{
void func ( void );
};

template<class T> void callClassSpecificFunc(T& t)
{
t.func();
}

int main()
{
Base b;
Derived d;
callClassSpecificFunc(b);
callClassSpecificFunc(d);
}


Now, you give me an example how it would be beneficial to disallow
that.

Victor



Back to top
Cy Edmunds
Guest





PostPosted: Tue Jun 24, 2003 1:50 am    Post subject: Re: Confused about non-virtual functions Reply with quote

"Robert William Vesterman" <bob (AT) vesterman (DOT) com> wrote

Quote:
Great, great, great. Thank you for the semantics lesson. Please
allow me to rephrase my question:

Please give me an example of why it is useful that C++ allows the
following:

class Base
{
void func ( void );
};

class Derived : public Base
{
void func ( void );
};

Thank you.

Bob Vesterman.

Well, that's an interesting point. It isn't something I would do with code I
wrote myself. But if Base was part of a library I was using it might turn
out to be a useful workaround.

I think the real reason for non-virtual functions is to avoid the overhead
of a virtual function call.



Back to top
Victor Bazarov
Guest





PostPosted: Tue Jun 24, 2003 2:00 am    Post subject: Re: Confused about non-virtual functions Reply with quote

"Cy Edmunds" <cedmunds (AT) spamless (DOT) rochester.rr.com> wrote...
Quote:
"Robert William Vesterman" <bob (AT) vesterman (DOT) com> wrote in message
news:jpaffv49jba3p7mcpaehueqrgbtqtl9vbd (AT) 4ax (DOT) com...
Great, great, great. Thank you for the semantics lesson. Please
allow me to rephrase my question:

Please give me an example of why it is useful that C++ allows the
following:

class Base
{
void func ( void );
};

class Derived : public Base
{
void func ( void );
};

Thank you.

Bob Vesterman.

Well, that's an interesting point. It isn't something I would do with code
I
wrote myself. But if Base was part of a library I was using it might turn
out to be a useful workaround.

I think the real reason for non-virtual functions is to avoid the overhead
of a virtual function call.

The reason for non-virtual functions is just because they exist. The
reason for _virtual_ functions is to implement polymorphism. People
tried to do away with non-virtual functions. What good did it do?
Nothing. Slow code and weird problems with calling virtual functions
for objects that haven't even begun constructing... Can you guess the
name of the language?

Victor



Back to top
Robert William Vesterman
Guest





PostPosted: Tue Jun 24, 2003 2:06 am    Post subject: Re: Confused about non-virtual functions Reply with quote

On Tue, 24 Jun 2003 01:44:44 GMT, "Victor Bazarov"
<v.Abazarov (AT) attAbi (DOT) com> wrote:

Quote:
"Robert William Vesterman" <bob (AT) vesterman (DOT) com> wrote...
Great, great, great. Thank you for the semantics lesson. Please
allow me to rephrase my question:

Please give me an example of why it is useful that C++ allows the
following:

class Base
{
void func ( void );
};

class Derived : public Base
{
void func ( void );
};

template<class T> void callClassSpecificFunc(T& t)
{
t.func();
}

int main()
{
Base b;
Derived d;
callClassSpecificFunc(b);
callClassSpecificFunc(d);
}

I'm sorry, I'm not seeing what you mean. How does the fact that
func() is not virtual figure into the use, or lack thereof, of the
above construct?

Thanks,

Bob Vesterman.

Back to top
Victor Bazarov
Guest





PostPosted: Tue Jun 24, 2003 3:41 am    Post subject: Re: Confused about non-virtual functions Reply with quote

"Robert William Vesterman" <bob (AT) vesterman (DOT) com> wrote...
Quote:
On Tue, 24 Jun 2003 01:44:44 GMT, "Victor Bazarov"
[email]v.Abazarov (AT) attAbi (DOT) com[/email]> wrote:

"Robert William Vesterman" <bob (AT) vesterman (DOT) com> wrote...
Great, great, great. Thank you for the semantics lesson. Please
allow me to rephrase my question:

Please give me an example of why it is useful that C++ allows the
following:

class Base
{
void func ( void );
};

class Derived : public Base
{
void func ( void );
};

template<class T> void callClassSpecificFunc(T& t)
{
t.func();
}

int main()
{
Base b;
Derived d;
callClassSpecificFunc(b);
callClassSpecificFunc(d);
}

I'm sorry, I'm not seeing what you mean. How does the fact that
func() is not virtual figure into the use, or lack thereof, of the
above construct?

It doesn't. That's the beauty of it. And, BTW, what the hell does
virtuality have to do with it? Didn't you say in your other posting
that you didn't want to compare them to virtual functions?

In the given example the fact that 'Derived' is derived from 'Base'
has no relevance. Two classes each has a function named 'func' with
a certain signature. Why should the language prohibit that? Please
abstract from "virtual" and get a simple fact: inheritance shouldn't
have any bearing on whether the language allows or prohibits to have
the same type function in two classes.

struct B { void f(); }; // OK?
struct D { void f(); }; // unrelated. Still OK?
struct DB : B { void f(); }; // related. Why not OK?

For the users of those classes there is no need to know whether DB
and B are related or not. Whenever 'f' is called, it will be the
right 'f'.

Victor



Back to top
David White
Guest





PostPosted: Tue Jun 24, 2003 5:52 am    Post subject: Re: Confused about non-virtual functions Reply with quote

Victor Bazarov <v.Abazarov (AT) attAbi (DOT) com> wrote

Quote:
In the given example the fact that 'Derived' is derived from 'Base'
has no relevance. Two classes each has a function named 'func' with
a certain signature. Why should the language prohibit that?

Perhaps because it's asking for trouble. I don't know about prohibit, but at
least warn.

Derived d;
Base *pb = &d;
Derived *pd = &d;
pb->f();
pd->f();

I don't think anyone would expect the two calls above to call different
functions.

David




Back to top
Karl Heinz Buchegger
Guest





PostPosted: Tue Jun 24, 2003 8:38 am    Post subject: Re: Confused about non-virtual functions Reply with quote



David White wrote:
Quote:

Victor Bazarov <v.Abazarov (AT) attAbi (DOT) com> wrote in message
news:ELPJa.5710$XG4.4416 (AT) rwcrnsc53 (DOT) ..
In the given example the fact that 'Derived' is derived from 'Base'
has no relevance. Two classes each has a function named 'func' with
a certain signature. Why should the language prohibit that?

Perhaps because it's asking for trouble. I don't know about prohibit, but at
least warn.

Derived d;
Base *pb = &d;
Derived *pd = &d;
pb->f();
pd->f();

I don't think anyone would expect the two calls above to call different
functions.

Please. Speak only for yourself. If my current situation asks for
calling different functions, then this is exactly what I expect
and this is exactly why I don't make that function virtual.


--
Karl Heinz Buchegger
[email]kbuchegg (AT) gascad (DOT) at[/email]

Back to top
Karl Heinz Buchegger
Guest





PostPosted: Tue Jun 24, 2003 8:39 am    Post subject: Re: Confused about non-virtual functions Reply with quote



Victor Bazarov wrote:
Quote:


The reason for non-virtual functions is just because they exist. The
reason for _virtual_ functions is to implement polymorphism. People
tried to do away with non-virtual functions. What good did it do?
Nothing. Slow code and weird problems with calling virtual functions
for objects that haven't even begun constructing... Can you guess the
name of the language?


Hmm. I guess I first need a cup of coffee :-)


--
Karl Heinz Buchegger
[email]kbuchegg (AT) gascad (DOT) at[/email]

Back to top
Karl Heinz Buchegger
Guest





PostPosted: Tue Jun 24, 2003 8:50 am    Post subject: Re: Confused about non-virtual functions Reply with quote



David White wrote:
Quote:

Robert William Vesterman <bob (AT) vesterman (DOT) com> wrote in message
news:ca2ffv0nshh91iibbihief64sothge3c4d (AT) 4ax (DOT) com...
I'm confused about the purpose of non-virtual functions. As I
understand it, if you have a class E that extends a class B and
overrides a non-virtual function f(), then the f() that actually gets
called for an E object depends upon whether that E object is known as
an E or as a B at the time of the call.

Here 'known as' means the declared type where the call is made, I take it.

Non-virtual functions are overwhelmingly those that are not overridden at
all. Their purpose is to do something that is not for overriding. Virtual
function calls require indirection, for which there is likely to be a
performance penalty, a penalty that is unnecessary if the function is not to
be overridden.

I don't understand what's useful about this ambiguity in what the f()
of an E is. Could someone please give me an example of why it would
be useful?

I can't think of one. I can't think of a circumstance in which I would
override a non-virtual function.


Very simple.
Imagine you have a class: Base
This class has member functions. In order to simplify things you decide
to factor out the common code and create a helper function for that:

class Base
{
void foo() { ...; Helper(); ... }
void foo2() { ...; Helper(); ... }

void Helper();
};

Now you derive a class from Base: Derived
It does the same thing: It has some functions and in order to
simplify things you factor out common code and put it into an Helper
function - which by accident gets the very same name as the
one in the base class.

class Derived : public Base
{
void foo3() { ...; Helper(); ... }
void foo4() { ...; Helper(); ... }

void Helper();
}

Now: If the correct job for Base::foo() and Base::foo2() is to use
Base::Helper() then you would be very surprised if Derived::Helper()
is called. If on the other hand the correct job for Base::foo()
and Base::foo2() is to use the Helper() from the most derived
class, then you declare Helper() as being virtual and be happy
with using polymorphism to do the job.

--
Karl Heinz Buchegger
[email]kbuchegg (AT) gascad (DOT) at[/email]

Back to top
David White
Guest





PostPosted: Tue Jun 24, 2003 10:07 am    Post subject: Re: Confused about non-virtual functions Reply with quote


"Karl Heinz Buchegger" <kbuchegg (AT) gascad (DOT) at> wrote

Quote:


David White wrote:
Perhaps because it's asking for trouble. I don't know about prohibit,
but at
least warn.

Derived d;
Base *pb = &d;
Derived *pd = &d;
pb->f();
pd->f();

I don't think anyone would expect the two calls above to call different
functions.

Please. Speak only for yourself. If my current situation asks for
calling different functions, then this is exactly what I expect
and this is exactly why I don't make that function virtual.

Then I'm sure glad I don't have to maintain any of your code.

David




Back to top
David White
Guest





PostPosted: Tue Jun 24, 2003 10:16 am    Post subject: Re: Confused about non-virtual functions Reply with quote

"Rob Williscroft" <rtw (AT) freenet (DOT) REMOVE.co.uk> wrote

Quote:
David White wrote in news:xGRJa.7685$eE.73366 (AT) nasal (DOT) pacific.net.au:

Perhaps because it's asking for trouble. I don't know about prohibit,
but at least warn.

Derived d;
Base *pb = &d;
Derived *pd = &d;
pb->f();
pd->f();

I don't think anyone would expect the two calls above to call
different functions.


The function call's have different signatures, maybe they resolve
(after conversion's) to the same function, maybe they don't.

In some header:

void func(Base *b);

In a possibly diffrent header:

void func(Derived *d);

In a xource file:

Derived d;
Base *pb = &d;
Derived *pd = &d;

func(pb);
func(pd);

It's called overloading and its a feature of the language.

Yes, I know.


Quote:
If you really must call the same function for both objects you can:

func(static_cast<Base *>(pb));
func(static_cast<Base *>(pd));

Or from your example:

pb->Base::f();
pd->Base::f();

This is actually better than my example as it avoids casts!
You can also select the overload with a cast:

// call func(static_cast<Base *>(pd));
static_cast< void (*)(Base *) >(func)(pd);

In real code you should avoid the casts and you *should*
expect the code that is executed by *any* expresion to be
dependant on the *static-types* involved.

This isn't relevant to the thread. We are talking about _overriding_ and the
presence/absence of the 'virtual' keyword. Overloading is a different matter

David




Back to top
David White
Guest





PostPosted: Tue Jun 24, 2003 10:23 am    Post subject: Re: Confused about non-virtual functions Reply with quote

"Karl Heinz Buchegger" <kbuchegg (AT) gascad (DOT) at> wrote

Quote:


David White wrote:

I can't think of one. I can't think of a circumstance in which I would
override a non-virtual function.


Very simple.
Imagine you have a class: Base
This class has member functions. In order to simplify things you decide
to factor out the common code and create a helper function for that:

class Base
{
void foo() { ...; Helper(); ... }
void foo2() { ...; Helper(); ... }

void Helper();
};

Now you derive a class from Base: Derived
It does the same thing: It has some functions and in order to
simplify things you factor out common code and put it into an Helper
function - which by accident gets the very same name as the
one in the base class.

class Derived : public Base
{
void foo3() { ...; Helper(); ... }
void foo4() { ...; Helper(); ... }

void Helper();
}

Now: If the correct job for Base::foo() and Base::foo2() is to use
Base::Helper() then you would be very surprised if Derived::Helper()
is called. If on the other hand the correct job for Base::foo()
and Base::foo2() is to use the Helper() from the most derived
class, then you declare Helper() as being virtual and be happy
with using polymorphism to do the job.

Well, I wouldn't do it. It's confusing and it's asking for trouble. Someone
not so familiar with the code might notice 'Helper' in the derived class's
interface, and later see the calls to 'Helper' in the base class function
bodies and assume that it's a virtual call. You might have the completely
wrong understanding of what's happening simply because you failed to notice
that there is no 'virtual' on the base-class declaration of 'Helper'().
Sorry, but I think this is ghastly.

David




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

 
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.