Confused with the "virtual base class" concept

M

mshetty

Hi,

I get an error "Warning: b::a_method hides the virtual function
a::a_method()."

on compiling the following code..

#include <iostream.h>
class a
{
public:
virtual int a_method ()
{
cout << "a::a_method" << endl;
return 0;
}
};

class b : public a
{
public:
int a_method (int x)
{
cout << "b::a_method" << endl;
return x;
}
};

class c : public a
{
public:
int a_method ()
{
cout << "c::a_method" << endl;
return 100;
}
};

int main()
{
b b_var;
b_var.a_method(10);
return 0;
}

The warning goes off if done the following:
Change class b : public a
to
class b : public virtual a

Have not been to understand the reason why the warning is removed as
"b::a_method still hides a::a_method()"

Would help if I could get some input.

Thanks and Regards,
M Shetty
 
D

David Harmon

On 29 Aug 2004 18:46:06 -0400 in comp.lang.c++, (e-mail address removed)
(mshetty) wrote,
I get an error "Warning: b::a_method hides the virtual function
a::a_method()."

This issue is covered in Marshall Cline's C++ FAQ. See the topic
"[23.6] What's the meaning of, Warning: Derived::f(float) hides
Base::f(int)?" It is always good to check the FAQ before posting.
You can get the FAQ at:
http://www.parashift.com/c++-faq-lite/
 
S

Sharad Kala

David Harmon said:
On 29 Aug 2004 18:46:06 -0400 in comp.lang.c++, (e-mail address removed)
(mshetty) wrote,
I get an error "Warning: b::a_method hides the virtual function
a::a_method()."

This issue is covered in Marshall Cline's C++ FAQ. See the topic
"[23.6] What's the meaning of, Warning: Derived::f(float) hides
Base::f(int)?" It is always good to check the FAQ before posting.
You can get the FAQ at:
http://www.parashift.com/c++-faq-lite/

Probably you are missing his question. He does know that the function is
being hidden, his question is about warnings getting removed after making
class A a virtual base.
To OP - Which compiler ? I get a warning with Comeau even after making it a
virtual base - "warning: function "a::a_method()" is hidden by
"b::a_method" -- virtual function override intended? int a_method (int x)"

-Sharad
 
I

Ivan Korotkov

I get an error "Warning: b::a_method hides the virtual function
a::a_method()."
class b : public a
{
public:
int a_method (int x)
{
cout << "b::a_method" << endl;
return x;
}
};

I don't know why virtual inheritance removes this, but when you declare an
overloaded function in derived class (b::a_method(int)) it hides all
functions with the same name from base class (a::a_method()). For example,
you can't call b.a_method(); If you include using a::a_method; in b
definition, a::a_method won't become hidden. Btw, you probably want to
declare a_method(int) as virtual, too, don't you?
 
C

Carl Barron

mshetty said:
Hi,

I get an error "Warning: b::a_method hides the virtual function
a::a_method()."

on compiling the following code..

#include <iostream.h>
class a
{
public:
virtual int a_method ()
{
cout << "a::a_method" << endl;
return 0;
}
};

class b : public a
{
public:
int a_method (int x)
{
cout << "b::a_method" << endl;
return x;
}
}
note well a::a_method() is a function with no args retuning int, and
b::a_method(int) is a function with an int arg returning int. Since b
has no method a_method() but one of a_method(int); it will hide [not
have available] the virtual function a_method(), if want the
vritual-ness of a_method() you must have such a function in b, since you
already have a a_method(int) which hides the defaulting a::method() of
being used, If you really want b::a_method_a(int) as well, then you need
a forwarding member function
void a_method() {a::a_method();} as well.

Virtual bases are used to provide just one base class of a type rather
then multiples in cases like this:

class Base{};
class Inbetween_1:public virtual Base{};
class Inbetween_2:public virtual Base{};
class TheWinner:public Inbetween_1,public Inbetween_2{};

this makes one instande of Base in an instance of TheWinner;

if the Inbetween's above were to each inherit Base non-virtually then
TheWinner would have two instances of Base namely
Inbetween_1::Base and Inbetween_2::Base. The class diagram of the
virtual inheritance case looks like a rhombus, and the non virtual
inheritance diagram looks like a Y.
 
M

Maxim Yegorushkin

[]
The warning goes off if done the following:
Change class b : public a
to
class b : public virtual a

Have not been to understand the reason why the warning is removed as
"b::a_method still hides a::a_method()"

It looks like poor diagnostic.
 
D

David Michell

I have added a line in class b.
read it.
hth
david michell

#include <iostream.h>
class a
{
public:
virtual int a_method ()
{
cout << "a::a_method" << endl;
return 0;
}
};

class b : public a
{
public:
virtual int a_method (){} /*ADD THIS LINE becaue
class c has to know that this method is virtual. It will not be taken
as default by inheritance*/


int a_method (int x)
{
cout << "b::a_method" << endl;
return x;
}
};

class c : public a
{
public:
int a_method ()
{
cout << "c::a_method" << endl;
return 100;
}
};

int main()
{
b b_var;
b_var.a_method(10);
return 0;
}
 
V

Vladislav Lazarenko

Hi,

I get an error "Warning: b::a_method hides the virtual function
a::a_method()."

on compiling the following code..

#include <iostream.h>
class a
{
public:
virtual int a_method ()
{
cout << "a::a_method" << endl;
return 0;
}
};

class b : public a
{
public:
int a_method (int x)
{
cout << "b::a_method" << endl;
return x;
}
};

class c : public a
{
public:
int a_method ()
{
cout << "c::a_method" << endl;
return 100;
}
};

int main()
{
b b_var;
b_var.a_method(10);
return 0;
}

The warning goes off if done the following:
Change class b : public a
to
class b : public virtual a

Have not been to understand the reason why the warning is removed as
"b::a_method still hides a::a_method()"

Would help if I could get some input.

Hi, mshetty. It is a silly warning, you can simply ignore it. For
example the Visual Studio .NET with 4 level (highest) of warning
messages did not generate it. But it is pretty-clear allusion to bad
design of your program.
 
I

Ivan Korotkov

public:
virtual int a_method (){} /*ADD THIS LINE becaue
class c has to know that this method is virtual. It will not be taken
as default by inheritance*/

class C inherits A directly, or is it a typo? Anyway, overriding a_method
as empty is not excellent, it's better to import it from A by using A::f;
in class B. Btw, which compiler did you use? VC++ understands that
a_method is virtual:

#include <iostream>

using namespace std;

class A { public : virtual void f() { cout << "In A::f\n"; } };
class B : public A { public: void f(int) {} };
class C : public B { public: void f() { cout << "In C::f\n"; }};

int main()
{
C c;

static_cast<A *>(&c)->f();

return 0;
}

yields

In C::f
 
M

Mike Bland

Hi,

I get an error "Warning: b::a_method hides the virtual function
a::a_method()."

on compiling the following code..
[snip]

The warning goes off if done the following:
Change class b : public a
to
class b : public virtual a

Have not been to understand the reason why the warning is removed as
"b::a_method still hides a::a_method()"

As others have pointed out, b::a_method() does hide a::a_method(), and
it seems it should hide it whether "a" is a virtual base of "b" or
not.

Intrigued by this, I tried your code under both GCC 3.4.1 and Sun CC
5.3 (WorkShop 6 Update 2) on Solaris 8, and was astonished by the
results:

`g++ -Wall -ansi -pedantic` compiled both the virtual and nonvirtual
versions without so much as a single warning (after changing
iostream.h to iostream and adding "using std::cout" and "using
std::endl" at the top). I tried this multiple times out of disbelief,
but the result was indeed the same each time; no mistyping on my part.

`CC +w2` produced the following results:

--BEGIN--
# CC +w2 virtual_base.cxx

"virtual_base.cxx", line 25: Warning: b::a_method hides the virtual
function a::a_method().
1 Warning(s) detected.

# vim virtual_base.cxx

[change base to virtual]

# CC +w2 virtual_base.cxx

"virtual_base.cxx", line 25: Warning: b::a_method Hides the virtual
function a::a_method() in a virtual base.
1 Warning(s) detected.
--END--

So now I'm even more confused. The Sun compiler seems to be right on
with this one, and GCC is oblivious, which is exactly backwards from
what I might've expected. What compiler and platform are you using,
M? Can anyone else provide some insight into what's going on?

Mike
 
M

Mike Bland

So now I'm even more confused. The Sun compiler seems to be right on
with this one, and GCC is oblivious, which is exactly backwards from
what I might've expected.

Whoops, after looking at the GCC info page, I realized that what I
need to use is -Woverloaded-virtual. Wonder why it's not
automatically a part of -Wall.

Still, I'd be interested in knowing which compiler the OP was using.

Mike
 
M

mshetty

Whoops, after looking at the GCC info page, I realized that what I
need to use is -Woverloaded-virtual. Wonder why it's not
automatically a part of -Wall.

Still, I'd be interested in knowing which compiler the OP was using.

Hi,

Details of the compiler and system I am using
Compiler : CC: Sun WorkShop 6 update 2 C++ 5.3 2001/05/15
OS : SunOS pcspsun3 5.7 Generic_106541-34 sun4u sparc SUNW,Ultra-5_10

Regards,
M Shetty
 
O

Old Wolf

Whoops, after looking at the GCC info page, I realized that what I
need to use is -Woverloaded-virtual. Wonder why it's not
automatically a part of -Wall.

No diagnostic is required by the Standard for the case of a function
hiding a base function (it's merely a quality-of-implementation issue).

Also -Wall is unfortunately-named, it should be -Wa-few-common-problems.
You should probably read the g++ documentation and add in lots more
-W settings to your Makefile.
 
M

Mike Bland

Details of the compiler and system I am using
Compiler : CC: Sun WorkShop 6 update 2 C++ 5.3 2001/05/15
OS : SunOS pcspsun3 5.7 Generic_106541-34 sun4u sparc SUNW,Ultra-5_10

Interesting. We're using the same Sun compiler, but I'm on patch
111685-20 dated 2004/03/19. You're using Solaris 7 and I'm on Solaris
8. Could be an issue with the compiler patchlevel, too. Try hitting
http://access1.sun.com/sundev/fdp6u2-patches.html to upgrade your
compiler patchlevel and see what happens.

Mike
 
M

Mike Bland

No diagnostic is required by the Standard for the case of a function
hiding a base function (it's merely a quality-of-implementation issue).

That's kinda surprising. Do you know if there are any plans to add
such a requirement?
Also -Wall is unfortunately-named, it should be -Wa-few-common-problems.
You should probably read the g++ documentation and add in lots more
-W settings to your Makefile.

LOL That's how I realized, eventually, that -Wall didn't contain
-Woverloaded-virtual. I mean, I've known for a long time that -Wall
didn't really turn on *all* warnings, but I was quite suprised when I
looked at the info page after my initial posting and realized it
didn't include this one by default.

Incidentally, I use a "pedantic" script that precompiles our sources
with g++ with various warnings explicitly turned on before compiling
them with Sun CC. It's worked out quite well for shaking out all
sorts of nasty errors and warnings.

Mike
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top