 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
DMan Guest
|
Posted: Thu Oct 09, 2003 8:40 pm Post subject: overloading of virtual functions |
|
|
Hi, All!
Suppose we have the following code:
class A
{
public:
virtual void f(){}
virtual void f( int ){}
};
class B: public A
{
public:
void f( char * ){} //Warinig: B::f(char*) hides virtual functions
A::f() and A::f(int)
};
int main()
{
A * a = new B;
B * b = new B;
a->f(); //ok
a->f( 1 ); //ok
b->f(); //Error: B::f() is not accessible
b->f( 1 ); //Error: B::f(int) is not accessible
delete a; delete b;
return 0;
}
Is this so by C++ standart or it is the problem of specific compiler?
I thought that when I declare void B::f(char*) I just create a new
version of function f (I mean overloading) that comes to B from it's
base class A!
I know one workaround for this situation:
if i bring declaration of A::f() and A::f(int) to the scope of class B
everything will be fine; here is an example of what I mean:
class B: public A
{
public:
using A::f;
void f(char*){};
};
Please, advise.
--
Best regards,
Dmitry Sidorchuk.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Attila Feher Guest
|
Posted: Fri Oct 10, 2003 7:47 pm Post subject: Re: overloading of virtual functions |
|
|
DMan wrote:
| Quote: | Hi, All!
Suppose we have the following code:
struct A {
virtual void f(){}
virtual void f( int ){}
};
struct B: A {
void f( char * ){} //Warning: B::f(char*) hides
// virtual functions A::f() and A::f(int)
};
[SNIP]
Is this so by C++ standart or it is the problem of specific compiler?
|
It is standard.
| Quote: | I thought that when I declare void B::f(char*) I just create a new
version of function f (I mean overloading) that comes to B from it's
base class A!
I know one workaround for this situation:
if i bring declaration of A::f() and A::f(int) to the scope of class
B everything will be fine; here is an example of what I mean:
class B: public A
{
public:
using A::f;
void f(char*){};
};
|
Perfect, AFAIK. And Bjarne Stroustup has this issue on his C++ FAQ page:
http://www.research.att.com/~bs/bs_faq2.html#overloadderived
--
Attila aka WW
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Josephine Schafer Guest
|
Posted: Fri Oct 10, 2003 7:53 pm Post subject: Re: overloading of virtual functions |
|
|
"DMan" <yasidor (AT) yahoo (DOT) com> wrote
| Quote: | Hi, All!
Suppose we have the following code:
class A
{
public:
virtual void f(){}
virtual void f( int ){}
};
class B: public A
{
public:
void f( char * ){} //Warinig: B::f(char*) hides virtual functions
A::f() and A::f(int)
};
int main()
{
A * a = new B;
B * b = new B;
a->f(); //ok
a->f( 1 ); //ok
b->f(); //Error: B::f() is not accessible
b->f( 1 ); //Error: B::f(int) is not accessible
delete a; delete b;
return 0;
}
Is this so by C++ standart or it is the problem of specific compiler?
|
Compiler is correct.
b->f() tries to invoke void f() in class B.
But this function has been hidden by void B::f(char*) and hence the compiler
error .
Note that b is not polymorphic and so the call gets evaluated statically.
Instead if you write
A *p = b;
p->f() //ok
A good compiler would warn you that you have hidden virtual base class function
and may be you wanted to override it.
HTH,
J.Schafer
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Christoph Schulz Guest
|
Posted: Sat Oct 11, 2003 3:09 pm Post subject: Re: overloading of virtual functions |
|
|
Hello!
DMan <yasidor (AT) yahoo (DOT) com> wrote:
| Quote: | Hi, All!
Suppose we have the following code:
class A
{
public:
virtual void f(){}
virtual void f( int ){}
};
class B: public A
{
public:
void f( char * ){} //Warinig: B::f(char*) hides virtual
functions A::f() and A::f(int)
};
int main()
{
A * a = new B;
B * b = new B;
a->f(); //ok
a->f( 1 ); //ok
b->f(); //Error: B::f() is not accessible
b->f( 1 ); //Error: B::f(int) is not accessible
delete a; delete b;
return 0;
}
Is this so by C++ standart or it is the problem of specific
compiler?
|
You're compiler is right. B and A are different scopes, although
B is a subclass of A. Overloading typically only works in a single
scope.
| Quote: |
I thought that when I declare void B::f(char*) I just create a new
version of function f (I mean overloading) that comes to B from
it's base class A!
I know one workaround for this situation:
if i bring declaration of A::f() and A::f(int) to the scope of
class B everything will be fine; here is an example of what I
mean:
class B: public A
{
public:
using A::f;
void f(char*){};
};
|
"using A::f" brings the name "f" into the scope of B, hence it
is available fo overloading.
By the way, the virtuality of "f" is not important in the example.
The behaviour (with regard to the semantics of overloading) would
be the same if both A::f methods were non-virtual.
Regards,
Christoph
[ 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
|
Posted: Sat Oct 11, 2003 3:19 pm Post subject: Re: overloading of virtual functions |
|
|
Josephine Schafer <no_spam_josschafer (AT) hotmail (DOT) com> schrieb in im
Newsbeitrag: bm5hrq$ievu7$1 (AT) ID-192448 (DOT) news.uni-berlin.de...
| Quote: |
"DMan" <yasidor (AT) yahoo (DOT) com> wrote in message
news:bm3mn2$20c$1 (AT) delta (DOT) teleportsv.net...
Hi, All!
Suppose we have the following code:
class A
{
public:
virtual void f(){}
virtual void f( int ){}
};
class B: public A
{
public:
void f( char * ){} //Warinig: B::f(char*) hides virtual functions
A::f() and A::f(int)
};
int main()
{
A * a = new B;
B * b = new B;
a->f(); //ok
a->f( 1 ); //ok
b->f(); //Error: B::f() is not accessible
b->f( 1 ); //Error: B::f(int) is not accessible
delete a; delete b;
return 0;
}
Is this so by C++ standart or it is the problem of specific compiler?
Compiler is correct.
b->f() tries to invoke void f() in class B.
But this function has been hidden by void B::f(char*) and hence the
compiler
error .
Note that b is not polymorphic and so the call gets evaluated statically.
Instead if you write
A *p = b;
p->f() //ok
|
What do you mean, "b is not polymorphic and so the call gets evaluated
statically"? Class B inherits two virtual functions from class A, so it IS
polymorphic.
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 |
|
 |
Francis Glassborow Guest
|
Posted: Sun Oct 12, 2003 12:43 am Post subject: Re: overloading of virtual functions |
|
|
In article <bm7f6c$d8r$1 (AT) news1 (DOT) nefonline.de>, Matthias Hofmann
<hofmann (AT) anvil-soft (DOT) com> writes
| Quote: | class A
{
public:
virtual void f(){}
virtual void f( int ){}
};
class B: public A
{
public:
void f( char * ){} //Warinig: B::f(char*) hides virtual
functions
A::f() and A::f(int)
};
int main()
{
A * a = new B;
B * b = new B;
a->f(); //ok
a->f( 1 ); //ok
b->f(); //Error: B::f() is not accessible
b->f( 1 ); //Error: B::f(int) is not accessible
delete a; delete b;
return 0;
}
Is this so by C++ standart or it is the problem of specific
compiler?
Compiler is correct.
b->f() tries to invoke void f() in class B.
But this function has been hidden by void B::f(char*) and hence the
compiler
error .
Note that b is not polymorphic and so the call gets evaluated
statically.
Instead if you write
A *p = b;
p->f() //ok
What do you mean, "b is not polymorphic and so the call gets evaluated
statically"? Class B inherits two virtual functions from class A, so it
IS
polymorphic.
|
There are two entirely distinct issues with the original code. The first
concerns name hiding. The declaration of an f in B hides all the
declarations of f's in A. To bring the declarations in A into the scope
of B (so overloading will happen) needs a using declaration.
The second issue is whether the compiler needs to use late binding to
determine the function to be called through b. The answer in the case
quoted is that it does not because it can determine the dynamic type of
b at compile time. There is no opportunity to rebind b to some other
object so b really is a pointer to a B.
--
Francis Glassborow ACCU
If you are not using up-to-date virus protection you should not be
reading
this. Viruses do not just hurt the infected but the whole community.
[ 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
|
Posted: Sun Oct 12, 2003 10:37 pm Post subject: Re: overloading of virtual functions |
|
|
----- Original Message -----
From: Francis Glassborow <francis (AT) robinton (DOT) demon.co.uk>
Newsgroups: comp.lang.c++.moderated
Sent: Sunday, October 12, 2003 2:43 AM
Subject: Re: overloading of virtual functions
| Quote: | In article <bm7f6c$d8r$1 (AT) news1 (DOT) nefonline.de>, Matthias Hofmann
[email]hofmann (AT) anvil-soft (DOT) com[/email]> writes
class A
{
public:
virtual void f(){}
virtual void f( int ){}
};
class B: public A
{
public:
void f( char * ){} //Warinig: B::f(char*) hides virtual
functions
A::f() and A::f(int)
};
int main()
{
A * a = new B;
B * b = new B;
a->f(); //ok
a->f( 1 ); //ok
b->f(); //Error: B::f() is not accessible
b->f( 1 ); //Error: B::f(int) is not accessible
delete a; delete b;
return 0;
}
Is this so by C++ standart or it is the problem of specific
compiler?
Compiler is correct.
b->f() tries to invoke void f() in class B.
But this function has been hidden by void B::f(char*) and hence the
compiler
error .
Note that b is not polymorphic and so the call gets evaluated
statically.
Instead if you write
A *p = b;
p->f() //ok
What do you mean, "b is not polymorphic and so the call gets evaluated
statically"? Class B inherits two virtual functions from class A, so it
IS
polymorphic.
There are two entirely distinct issues with the original code. The first
concerns name hiding. The declaration of an f in B hides all the
declarations of f's in A. To bring the declarations in A into the scope
of B (so overloading will happen) needs a using declaration.
The second issue is whether the compiler needs to use late binding to
determine the function to be called through b. The answer in the case
quoted is that it does not because it can determine the dynamic type of
b at compile time. There is no opportunity to rebind b to some other
object so b really is a pointer to a B.
|
I am a little confused know. As far as I see things, the reason that the
compiler does not need to use late binding in the case mentioned is, that
due to the fact that B::f() is hiding all A::f() functions, there is only a
single f() in B, and it is not virtual. Thus, b->f() tries to call the only
available B::f( char* ), and as the arguments do not match, you get an
error.
Please explain how the compiler can "determine the dynamic type of b at
compile time". As far as I know, the dynamic type can never be determined at
compile time when dealing with pointers to class objects. Of course, the
dynamic type is only of interest for virtual functions.
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 |
|
 |
Francis Glassborow Guest
|
Posted: Mon Oct 13, 2003 8:50 pm Post subject: Re: overloading of virtual functions |
|
|
In article <bmbe59$j71$1 (AT) news1 (DOT) nefonline.de>, Matthias Hofmann
<hofmann (AT) anvil-soft (DOT) com> writes
| Quote: | Please explain how the compiler can "determine the dynamic type of b at
compile time". As far as I know, the dynamic type can never be determined at
compile time when dealing with pointers to class objects. Of course, the
dynamic type is only of interest for virtual functions.
|
int main(){
base * b_ptr = new derived;
b_ptr->something();
...
}
The compiler can determine that b_ptr necessarily has the dynamic type
derived*. Even when there are intervening statements such determinations
are possible whenever the pointer variable is not passed by reference or
by pointer to another function. Of course we rarely use entirely local
dynamic polymorphic objects, but that is beside the point. The compiler
is allowed to apply static binding wherever it can determine the dynamic
type unambiguously.
--
Francis Glassborow ACCU
If you are not using up-to-date virus protection you should not be reading
this. Viruses do not just hurt the infected but the whole community.
[ 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
|
Posted: Tue Oct 14, 2003 9:09 am Post subject: Re: overloading of virtual functions |
|
|
Francis Glassborow <francis (AT) robinton (DOT) demon.co.uk> schrieb in im Newsbeitrag:
wsy5$SDjMoi$EwRO (AT) robinton (DOT) demon.co.uk...
| Quote: | In article <bmbe59$j71$1 (AT) news1 (DOT) nefonline.de>, Matthias Hofmann
[email]hofmann (AT) anvil-soft (DOT) com[/email]> writes
Please explain how the compiler can "determine the dynamic type of b at
compile time". As far as I know, the dynamic type can never be determined
at
compile time when dealing with pointers to class objects. Of course, the
dynamic type is only of interest for virtual functions.
int main(){
base * b_ptr = new derived;
b_ptr->something();
...
}
The compiler can determine that b_ptr necessarily has the dynamic type
derived*. Even when there are intervening statements such determinations
are possible whenever the pointer variable is not passed by reference or
by pointer to another function. Of course we rarely use entirely local
dynamic polymorphic objects, but that is beside the point. The compiler
is allowed to apply static binding wherever it can determine the dynamic
type unambiguously.
|
Oh, I see. Then the compiler might even be able to inline a virtual function
in this case?
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 |
|
 |
Francis Glassborow Guest
|
Posted: Tue Oct 14, 2003 8:46 pm Post subject: Re: overloading of virtual functions |
|
|
In article <bmf78o$kp$1 (AT) news1 (DOT) nefonline.de>, Matthias Hofmann
<hofmann (AT) anvil-soft (DOT) com> writes
| Quote: | int main(){
base * b_ptr = new derived;
b_ptr->something();
...
}
The compiler can determine that b_ptr necessarily has the dynamic type
derived*. Even when there are intervening statements such determinations
are possible whenever the pointer variable is not passed by reference or
by pointer to another function. Of course we rarely use entirely local
dynamic polymorphic objects, but that is beside the point. The compiler
is allowed to apply static binding wherever it can determine the dynamic
type unambiguously.
Oh, I see. Then the compiler might even be able to inline a virtual function
in this case?
|
In simple terms, yes. And I think some do. Note that the only practical
use (that I know of) for this kind of code is to place an object with a
large base footprint off the stack. This has become increasingly
unnecessary as class designers switch to using a PImpl when designing
such types.
--
Francis Glassborow ACCU
If you are not using up-to-date virus protection you should not be reading
this. Viruses do not just hurt the infected but the whole community.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ben Hutchings Guest
|
Posted: Tue Oct 14, 2003 8:59 pm Post subject: Re: overloading of virtual functions |
|
|
In article <bm3mn2$20c$1 (AT) delta (DOT) teleportsv.net>, DMan wrote:
| Quote: | Hi, All!
Suppose we have the following code:
class A
{
public:
virtual void f(){}
virtual void f( int ){}
};
class B: public A
{
public:
void f( char * ){} //Warinig: B::f(char*) hides virtual functions
A::f() and A::f(int)
};
snip
Is this so by C++ standart or it is the problem of specific compiler?
|
This is standard behaviour. By the way, it doesn't matter whether the
hidden functions are virtual.
| Quote: | I thought that when I declare void B::f(char*) I just create a new
version of function f (I mean overloading) that comes to B from it's
base class A!
|
But it can be confusing if a function name is overloaded to refer to
functions defined in several different classes. So that is not the
normal behaviour.
Also the warning will appear if you intend to override a virtual
function but get the signature (aside from the name) wrong.
| Quote: | I know one workaround for this situation:
if i bring declaration of A::f() and A::f(int) to the scope of class B
everything will be fine; here is an example of what I mean:
class B: public A
{
public:
using A::f;
void f(char*){};
};
Please, advise.
|
That is the standard and correct way to do what you want.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Thomas Richter Guest
|
Posted: Tue Oct 14, 2003 9:07 pm Post subject: Re: overloading of virtual functions |
|
|
Hi,
| Quote: | The compiler can determine that b_ptr necessarily has the dynamic type
derived*. Even when there are intervening statements such determinations
are possible whenever the pointer variable is not passed by reference or
by pointer to another function. Of course we rarely use entirely local
dynamic polymorphic objects, but that is beside the point. The compiler
is allowed to apply static binding wherever it can determine the dynamic
type unambiguously.
|
| Quote: | Oh, I see. Then the compiler might even be able to inline a virtual function
in this case?
|
Yes, indeed. Some compilers actually do; IIRC, I've seen the GNU g++
doing this.
So long,
Thomas
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Josephine Schafer Guest
|
Posted: Wed Oct 15, 2003 12:45 pm Post subject: Re: overloading of virtual functions |
|
|
| Quote: | Please explain how the compiler can "determine the dynamic type of b at
compile time". As far as I know, the dynamic type can never be determined at
compile time when dealing with pointers to class objects. Of course, the
dynamic type is only of interest for virtual functions.
|
The question to ask is whether compiler can bind b to some other object at run
time ?
Ans : No
So,
1. What is the static type of b?
Ans :B*
2. What is the dynamic type of b?
Ans :B*
HTH,
J.Schafer
[ 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
|
Posted: Thu Oct 16, 2003 2:43 pm Post subject: Re: overloading of virtual functions |
|
|
Josephine Schafer <no_spam_josschafer (AT) hotmail (DOT) com> schrieb in im
Newsbeitrag: bmde2l$l87am$1 (AT) ID-192448 (DOT) news.uni-berlin.de...
| Quote: | Please explain how the compiler can "determine the dynamic type of b at
compile time". As far as I know, the dynamic type can never be
determined at
compile time when dealing with pointers to class objects. Of course,
the
dynamic type is only of interest for virtual functions.
The question to ask is whether compiler can bind b to some other object at
run
time ?
Ans : No
So,
1. What is the static type of b?
Ans :B*
2. What is the dynamic type of b?
Ans :B*
|
This brings me to an idea. If the compiler can determine the dynamic type in
the case described, then the following could theorectically work:
struct A {};
struct B : public A
{
void f();
};
int main()
{
A* pa = new B;
pa->f(); // Error, there's no f() in A!
}
Actually, the call to A::f() could work, making a dynamic_cast redundant.
But of course, optimizations should not undermine legality of code...
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 |
|
 |
Josephine Schafer Guest
|
Posted: Fri Oct 17, 2003 11:19 am Post subject: Re: overloading of virtual functions |
|
|
"Matthias Hofmann" <hofmann (AT) anvil-soft (DOT) com> wrote
| Quote: |
Josephine Schafer <no_spam_josschafer (AT) hotmail (DOT) com> schrieb in im
Newsbeitrag: bmde2l$l87am$1 (AT) ID-192448 (DOT) news.uni-berlin.de...
Please explain how the compiler can "determine the dynamic type of b at
compile time". As far as I know, the dynamic type can never be
determined at
compile time when dealing with pointers to class objects. Of course,
the
dynamic type is only of interest for virtual functions.
The question to ask is whether compiler can bind b to some other object at
run
time ?
Ans : No
So,
1. What is the static type of b?
Ans :B*
2. What is the dynamic type of b?
Ans :B*
This brings me to an idea. If the compiler can determine the dynamic type in
the case described, then the following could theorectically work:
struct A {};
struct B : public A
{
void f();
};
int main()
{
A* pa = new B;
pa->f(); // Error, there's no f() in A!
}
Actually, the call to A::f() could work, making a dynamic_cast redundant.
But of course, optimizations should not undermine legality of code...
|
See in the case you have quoted compiler can clearly see that the static type of
pa is A*.
It can also see that it can rebind it to some other object at run time.
But as far as the compilation is concerned it will look for f() in struct A only
i.e using the static type only.
Hence you get the error.
HTH,
J.Schafer
(Remove no_spam_ to contact by mail.)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
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
|
|