By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,190 Members | 811 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,190 IT Pros & Developers. It's quick & easy.

another c++ inheretence/virtual quesion

P: n/a
Hi. I have a simple question, but I couldnt find the answer in any
literature online.

i have a base class A, that has some functions. now, my understanding
of virtual functions means that in:

class A {
virtual void foo() = 0;
void bar() {cout<<"bar"<<endl;}
};

class B : public A {
void foo() {cout<<"foo"<<endl;}
void bar() {cout<<"bar2"<<endl;}
};

every class B that derives class A *must* define foo or I get a linker
error.

also, if class B defines bar, it will call the bar from class A rather
than B. i.e. print out bar rather than bar2

What i want is to have a function defined in A that if it isnt defined
in B, then it uses the one in A

if it is defined in B, then it uses the one in B. (but it doesnt
*have* to be defined) how do i do this? thanks!

oliver

Jul 23 '05 #1
Share this Question
Share on Google+
17 Replies


P: n/a
This is pretty much done in your example. Since you have bar() defined in
A, if it is not defined in B the version in the base class will be called
(provided all pure virtual functions are defined which you have done)

On Wed, 13 Apr 2005 20:46:26 -0700, laniik wrote:
Hi. I have a simple question, but I couldnt find the answer in any
literature online.

i have a base class A, that has some functions. now, my understanding
of virtual functions means that in:

class A {
virtual void foo() = 0;
void bar() {cout<<"bar"<<endl;}
};
class B : public A {
void foo() {cout<<"foo"<<endl;}
void bar() {cout<<"bar2"<<endl;}
};

every class B that derives class A *must* define foo or I get a linker
error.

also, if class B defines bar, it will call the bar from class A rather
than B. i.e. print out bar rather than bar2

What i want is to have a function defined in A that if it isnt defined
in B, then it uses the one in A

if it is defined in B, then it uses the one in B. (but it doesnt
*have* to be defined) how do i do this? thanks!

oliver


Jul 23 '05 #2

P: n/a
thats what I first thought, but when i compiled and tested it out,
calling

B b;
b.bar();

would print out "bar" rather than "bar2"

Jul 23 '05 #3

P: n/a
What platform are you on?

On Wed, 13 Apr 2005 21:08:30 -0700, laniik wrote:
thats what I first thought, but when i compiled and tested it out,
calling

B b;
b.bar();

would print out "bar" rather than "bar2"


Jul 23 '05 #4

P: n/a
"laniik" <la****@yahoo.com> wrote in message
news:11**********************@l41g2000cwc.googlegr oups.com...
Hi. I have a simple question, but I couldnt find the answer in any
literature online.

i have a base class A, that has some functions. now, my understanding
of virtual functions means that in:

class A {
virtual void foo() = 0;
void bar() {cout<<"bar"<<endl;}
};

class B : public A {
void foo() {cout<<"foo"<<endl;}
void bar() {cout<<"bar2"<<endl;}
};

every class B that derives class A *must* define foo or I get a linker
error.
No. You get a compiler error if you try to create an instance of A, or a
class derived directly or indirectly from A that does not provide or inherit
a non-pure override of A::foo.

You get a linker error if you call a function that you've declared but
haven't defined anywhere, whether it's virtual or not. You might or might
not get a linker error for declaring a non-pure virtual function that you
haven't defined, even if you don't call it. That probably depends on the
linker, but certainly the ones I've used would give an error.
also, if class B defines bar, it will call the bar from class A rather
than B. i.e. print out bar rather than bar2
What do you mean by 'it' in this statement? B::bar hides A::bar (and B::foo
hides A::foo for that matter). If you have a B, B& or B* and you call bar(),
then B::bar will be called.
What i want is to have a function defined in A that if it isnt defined
in B, then it uses the one in A

if it is defined in B, then it uses the one in B. (but it doesnt
*have* to be defined) how do i do this? thanks!


That just happens naturally. That's why it's called *inheritance*. If a
given class doesn't have a particular member, then it will inherit it from
the nearest base class that has it. Try removing bar() from B, then create a
B object and call its bar(). A::bar will be called.

DW
Jul 23 '05 #5

P: n/a
I put basically your same code in from your top level message and it
worked fine:
#include <iostream>

using std::cout;

class A
{
public:
A(){}
virtual void foo()=0;
void bar()
{
cout<<"bar\n";
}
};

class B : public A
{
public:
B(){}
virtual void foo()
{
cout<<"Foo\n";
}
void bar()
{
cout<<"bar2\n";
}
};

int main(int argc, char **argv)
{
B b;
b.bar();

return 0;
}

results in "bar2" being printed.
On Wed, 13 Apr 2005 21:08:30 -0700, laniik wrote:
thats what I first thought, but when i compiled and tested it out,
calling

B b;
b.bar();

would print out "bar" rather than "bar2"


Jul 23 '05 #6

P: n/a
> also, if class B defines bar, it will call the bar from class A rather
than B. i.e. print out bar rather than bar2
No it won't.

A *pa = new B;
B *pb = new B;

pa->foo(); // will display "foo"
pa->bar(); // will display "bar"

pb->foo(); // will display "foo"
pb->bar(); // will display "bar2"
What i want is to have a function defined in A that if it isnt defined
in B, then it uses the one in A

if it is defined in B, then it uses the one in B. (but it doesnt
*have* to be defined) how do i do this? thanks!
It depends on what object type "it" is.
virtual member functions are dynamically bound.
non-virtual member functions depend on the type of the object.

Stephen Howe
oliver

Jul 23 '05 #7

P: n/a
> thats what I first thought, but when i compiled and tested it out,
calling

B b;
b.bar();

would print out "bar" rather than "bar2"


Something wrong then.
You should see "bar2".

Stephen Howe
Jul 23 '05 #8

P: n/a
i dont know what to say, im looking at it right now, its definitly
calling the function from the base class.

this is the code posted above.

i am using g++ on a solaris machine. any ideas?

Jul 23 '05 #9

P: n/a
found the bug: turns out you need to have bar declared virtual as
well...

Jul 23 '05 #10

P: n/a
"laniik" <la****@yahoo.com> wrote in message
news:11**********************@z14g2000cwz.googlegr oups.com...
found the bug: turns out you need to have bar declared virtual as
well...


No you don't. The behaviour you have described is wrong, and it is hard to
believe that any reasonably tried and tested compiler could have such a
fundamental problem. I suggest that you post the complete and exact code
you've compiled and run by pasting it from the file you compiled into your
newsreader (the code you originally posted is not a complete program, nor
does it compile as is).

DW
Jul 23 '05 #11

P: n/a
class A {
public:
void go() {cout<<"1"<<endl;}
};

class B : public A{
public:
void go() {cout<<"2"<<endl;}
};

int main()
{
B b;
b.go();
return 0;
}

tried this in visual studio .net 2003, printed "2"
tried this on solaris (not sure what version) with g++ (also not sure
what version) printed "1"

Jul 23 '05 #12

P: n/a
"laniik" <la****@yahoo.com> wrote in message
news:11**********************@l41g2000cwc.googlegr oups.com...
class A {
public:
void go() {cout<<"1"<<endl;}
};

class B : public A{
public:
void go() {cout<<"2"<<endl;}
};

int main()
{
B b;
b.go();
return 0;
}
This still isn't complete and can't be what you compiled. You didn't
#include <iostream> and you haven't got any std::. It probably doesn't
matter, assuming that all that's missing from your post is the bare minimum
to get it to compile, but when a program behaves as wrongly as you describe,
it's best to post _exactly_ what you compiled to remove all doubt that
something you haven't included in your post is causing the problem.
tried this in visual studio .net 2003, printed "2"
As it should.
tried this on solaris (not sure what version) with g++ (also not sure
what version) printed "1"


Well, that's amazing.

DW
Jul 23 '05 #13

P: n/a
yea i cant cut and paste because i am using a differnt computer for the
newsgroups as the coding. but regardless, all that was missing was the
#include and the namespace.

so, it does perform as desired when i make the functions virtual, is
there any reason i wouldnt want to just do that?

thanks

Jul 23 '05 #14

P: n/a
laniik wrote:
class A {
public:
void go() {cout<<"1"<<endl;}
};

class B : public A{
public:
void go() {cout<<"2"<<endl;}
};

int main()
{
B b;
b.go();
return 0;
}

tried this in visual studio .net 2003, printed "2"
tried this on solaris (not sure what version) with g++ (also not sure
what version) printed "1"


This prints "2" when compiled with GCC g++ v3.3.4 on
linux (SuSE Pro v9.2):

#include <iostream>

class A {
public:
void go() {std::cout << "1" << std::endl;}
};

class B : public A{
public:
void go() {std::cout << "2" << std::endl;}
};

int main()
{
B b;
b.go();
return 0;
}

Regards,
Larry

--
Anti-spam address, change each 'X' to '.' to reply directly.
Jul 23 '05 #15

P: n/a
"laniik" <la****@yahoo.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...
yea i cant cut and paste because i am using a differnt computer for the
newsgroups as the coding. but regardless, all that was missing was the
#include and the namespace.

so, it does perform as desired when i make the functions virtual, is
there any reason i wouldnt want to just do that?


It is very unusual for a function such as your 'go' not to be virtual. If
your object is really a B then almost always you would want to call B::go
even if you access it through an A& or A*, e.g.,
B b;
b.go(); // 1
A &a = b;
a.go(); // 2

Only if you actually wanted B::go to be called in case 1 and A::go to be
called in case 2 would you not make it virtual. The reason is that it's the
same object in each case, so you normally want the same function to be
called. This is object-oriented polymorphism. So, unless you have a
compelling reason not to, you should make it virtual (and you'll need a
virtual destructor in A if you do).

DW
Jul 23 '05 #16

P: n/a
laniik wrote:

yea i cant cut and paste because i am using a differnt computer for the
newsgroups as the coding. but regardless, all that was missing was the
#include and the namespace.

so, it does perform as desired when i make the functions virtual, is
there any reason i wouldnt want to just do that?


If that code really perfomrs that way on solaris, then there
is only one thing you want to do: get a different compiler, it
has a strange and serious bug. There is no point in using
it any longer.

But honestly: I doubt that this compiler has that bug. A bug like
this would be discovered in even the simplest compiler tests.
--
Karl Heinz Buchegger
kb******@gascad.at
Jul 23 '05 #17

P: n/a
well, i went and got a new g++, and it works fine now. soooo dunno why
it wasnt working. before

but thanks david, that helps me understand the virtual/nonvirtual
distinction more.

oliver

Jul 23 '05 #18

This discussion thread is closed

Replies have been disabled for this discussion.