Connecting Tech Pros Worldwide Help | Site Map

calling virtual function results in calling function of base class...

  #1  
Old July 23rd, 2005, 12:32 AM
Andreas Lagemann
Guest
 
Posts: n/a
Hi,
after browsing FAQ and archive for a while I decided that the following
is a legal question.

Consider this:

Class Base
{
public:
Base() {}

Base(A* a, B* b);

virtual A* foo(P* p, S& s); // using myA and myB
protected:
A* myA;
B* myB;
};

class Der : public Base
{
public:
Der(O* o) : Base(), myO(o) {}
A* foo(P* p; S& s); // not using myA and myB
private:
O* myO;
};

class Bogus
{
public:
Bogus(Base* b) : myBase(b) {}

void bar()
{
...
myBase->foo(p,s);
...
}
private:
Base* myBase;
};

int main(/*args*/)
{
...
Der der(someO);
Bogus* bogus = new Bogus(der);
...
bogus->bar();
...
};

Executing this results in Base::foo being called instead of Der::foo
(what I would expect) ....
What am I doing wrong ?
Is that because cstr of Der does not initialize any mebers of Base ?
How could I possibly avoid that or get the behaviour I need ?
Pleas help!!!

Regards,

Andreas Lagemann
  #2  
Old July 23rd, 2005, 12:32 AM
Mike Wahler
Guest
 
Posts: n/a

re: calling virtual function results in calling function of base class...



"Andreas Lagemann" <andreas.lagemann@freenet.de> wrote in message
news:41e1796d$0$30345$9b622d9e@news.freenet.de...[color=blue]
> Hi,
> after browsing FAQ and archive for a while I decided that the following
> is a legal question.
>
> Consider this:
>
> Class Base
> {
> public:
> Base() {}
>
> Base(A* a, B* b);[/color]

This won't compile because types 'A' and 'B' have
not been declared at this point.
[color=blue]
>
> virtual A* foo(P* p, S& s); // using myA and myB[/color]

None of types 'A', 'P', or 'S' have been declared
at this point.
[color=blue]
> protected:
> A* myA;
> B* myB;
> };
>
> class Der : public Base
> {
> public:
> Der(O* o) :[/color]
[color=blue]
> Base(),[/color]

This will happen automatically, you need not specify it.
[color=blue]
> myO(o) {}
> A* foo(P* p; S& s); // not using myA and myB[/color]

None of the types 'A', 'P', or 'S' have been declared
at this point.
[color=blue]
> private:
> O* myO;
> };
>
> class Bogus
> {
> public:
> Bogus(Base* b) : myBase(b) {}
>
> void bar()
> {
> ...
> myBase->foo(p,s);
> ...
> }
> private:
> Base* myBase;
> };
>
> int main(/*args*/)
> {
> ...
> Der der(someO);
> Bogus* bogus = new Bogus(der);
> ...
> bogus->bar();
> ...
> };
>
> Executing this results in Base::foo being called instead of Der::foo
> (what I would expect) ....
> What am I doing wrong ?[/color]

Misunderstanding. 'Base::foo()' is being called because you
supplied a pointer to a 'Base' object. If you want 'Der::foo'
to be called, you need to suppy the address of (or a reference to)
a type 'Der' object.
[color=blue]
> Is that because cstr of Der does not initialize any mebers of Base ?[/color]

No.
[color=blue]
> How could I possibly avoid that or get the behaviour I need ?[/color]


If you want to call a function of 'Der' via a pointer to its
base, intialize the base pointer with the address of a 'Der'
object.

-Mike


  #3  
Old July 23rd, 2005, 12:32 AM
Andreas Lagemann
Guest
 
Posts: n/a

re: calling virtual function results in calling function of base class...


Mike Wahler schrieb:[color=blue]
> "Andreas Lagemann" <andreas.lagemann@freenet.de> wrote in message
> news:41e1796d$0$30345$9b622d9e@news.freenet.de...
>[color=green]
>>Hi,
>>after browsing FAQ and archive for a while I decided that the following
>>is a legal question.
>>
>>Consider this:
>>
>>Class Base
>>{
>>public:
>>Base() {}
>>
>>Base(A* a, B* b);[/color]
>
>
> This won't compile because types 'A' and 'B' have
> not been declared at this point.
>
>[color=green]
>>virtual A* foo(P* p, S& s); // using myA and myB[/color]
>
>
> None of types 'A', 'P', or 'S' have been declared
> at this point.
>[/color]
Yes, I just wanted to keep the posting short, the exact form of A, B, P,
S is irrelevant to the question (I think), Sorry for not mentioning that.[color=blue][color=green]
>>protected:
>>A* myA;
>>B* myB;
>>};
>>
>>class Der : public Base
>>{
>>public:
>>Der(O* o) :[/color]
>
>[color=green]
>>Base(),[/color]
>
>
> This will happen automatically, you need not specify it.
>[/color]
I know that, I just wanted to stress the fact that I call the std. cstr
at that point.[color=blue]
>[color=green]
>>myO(o) {}
>>A* foo(P* p; S& s); // not using myA and myB[/color]
>
>
> None of the types 'A', 'P', or 'S' have been declared
> at this point.
>[/color]
see above
[color=blue][color=green]
>>private:
>>O* myO;
>>};
>>
>>class Bogus
>>{
>>public:
>>Bogus(Base* b) : myBase(b) {}
>>
>>void bar()
>>{
>> ...
>> myBase->foo(p,s);
>> ...
>>}
>>private:
>>Base* myBase;
>>};
>>
>>int main(/*args*/)
>>{
>>...
>>Der der(someO);
>>[/color][/color]

[edit] Bogus* bogus = new Bogus(&der);
^^^^
that was what I meant ...
[color=blue][color=green]
>>...
>>bogus->bar();
>>...
>>};
>>
>>Executing this results in Base::foo being called instead of Der::foo
>>(what I would expect) ....
>>What am I doing wrong ?[/color]
>
>
> Misunderstanding. 'Base::foo()' is being called because you
> supplied a pointer to a 'Base' object. If you want 'Der::foo'
> to be called, you need to suppy the address of (or a reference to)
> a type 'Der' object.
>[/color]
Sorry but as far as I understand, I supplied a pointer (sorry for the
typo) to Der (i.e. &der) when initializing Bogus. Therefore if I call
bogus->bar() Der::foo should be called, shouldn´t it ?[color=blue]
>[color=green]
>>Is that because cstr of Der does not initialize any mebers of Base ?[/color]
>
>
> No.
>
>[color=green]
>>How could I possibly avoid that or get the behaviour I need ?[/color]
>
>
>
> If you want to call a function of 'Der' via a pointer to its
> base, intialize the base pointer with the address of a 'Der'
> object.[/color]

I thought that was what I have done !? (see above)

Perhaps another Question for clarification:
I want to be able to call a specialized versions of a certain function
without knowing the exact type of specialization at compile time. That
is what I thought virtual functions were intended for ...

Can please anyone point out, how I could achieve such a behaviour ?

Regards and thanks for the answer so far,

Andreas
  #4  
Old July 23rd, 2005, 12:32 AM
Mike Wahler
Guest
 
Posts: n/a

re: calling virtual function results in calling function of base class...



"Andreas Lagemann" <andreas.lagemann@freenet.de> wrote in message
news:41e1875a$0$1546$9b622d9e@news.freenet.de...[color=blue]
> Mike Wahler schrieb:[color=green]
> > "Andreas Lagemann" <andreas.lagemann@freenet.de> wrote in message[/color][/color]
[color=blue][color=green]
> > Misunderstanding. 'Base::foo()' is being called because you
> > supplied a pointer to a 'Base' object. If you want 'Der::foo'
> > to be called, you need to suppy the address of (or a reference to)
> > a type 'Der' object.
> >[/color]
> Sorry but as far as I understand, I supplied a pointer (sorry for the
> typo) to Der (i.e. &der) when initializing Bogus. Therefore if I call
> bogus->bar() Der::foo should be called, shouldn´t it ?[/color]

'bogus' is not a pointer to your base class. It's a pointer
to a type 'Bogus' object.
[color=blue]
> Perhaps another Question for clarification:
> I want to be able to call a specialized versions of a certain function
> without knowing the exact type of specialization at compile time. That
> is what I thought virtual functions were intended for ...
>
> Can please anyone point out, how I could achieve such a behaviour ?[/color]

Assign the address of a derived object to a pointer to an object
of its base class.

#include <iostream>

class Base
{
public:
virtual void f() { std::cout << "base\n"; }
};

class Derived : public Base
{
public:
void f() { std::cout << "derived\n"; }
};

int main()
{
base *b1 = new Base;
base *b2 = new Derived;
b1->f(); /* prints "base" */
b2->f(); /* prints "derived" */
delete b1;
delete b2;
return 0;
}

-Mike


  #5  
Old July 23rd, 2005, 12:32 AM
Andreas Lagemann
Guest
 
Posts: n/a

re: calling virtual function results in calling function of base class...


Mike Wahler schrieb:[color=blue]
> "Andreas Lagemann" <andreas.lagemann@freenet.de> wrote in message
> news:41e1875a$0$1546$9b622d9e@news.freenet.de...
>[color=green]
>>Mike Wahler schrieb:
>>[color=darkred]
>>>"Andreas Lagemann" <andreas.lagemann@freenet.de> wrote in message[/color][/color]
>
>[color=green][color=darkred]
>>>Misunderstanding. 'Base::foo()' is being called because you
>>>supplied a pointer to a 'Base' object. If you want 'Der::foo'
>>>to be called, you need to suppy the address of (or a reference to)
>>>a type 'Der' object.
>>>[/color]
>>
>>Sorry but as far as I understand, I supplied a pointer (sorry for the
>>typo) to Der (i.e. &der) when initializing Bogus. Therefore if I call
>>bogus->bar() Der::foo should be called, shouldn´t it ?[/color]
>
>
> 'bogus' is not a pointer to your base class. It's a pointer
> to a type 'Bogus' object.
>[/color]
Yes, but Bogus has a member of type Base*, which is initialized with a
pointer to Der.

Oh I just realized that I made another error defining Bogus::bar().
It should be

A* Bogus::bar()
^^
{
...
return myBase->foo();
^^^^^^
...
}

So any instance of Bogus initialized with a pointer to Der should
execute Der::foo when Bogus::bar() is called. Is that right ?
[color=blue]
>[color=green]
>>Perhaps another Question for clarification:
>>I want to be able to call a specialized versions of a certain function
>>without knowing the exact type of specialization at compile time. That
>>is what I thought virtual functions were intended for ...
>>
>>Can please anyone point out, how I could achieve such a behaviour ?[/color]
>
>
> Assign the address of a derived object to a pointer to an object
> of its base class.
>
> #include <iostream>
>
> class Base
> {
> public:
> virtual void f() { std::cout << "base\n"; }
> };
>
> class Derived : public Base
> {
> public:
> void f() { std::cout << "derived\n"; }
> };
>
> int main()
> {
> base *b1 = new Base;
> base *b2 = new Derived;
> b1->f(); /* prints "base" */
> b2->f(); /* prints "derived" */
> delete b1;
> delete b2;
> return 0;
> }[/color]

That´s just how I thought it should work. So my example should work the
same way, doesn´t it ?

Thank you very much for your patience, I´m kinda confused by now ...

Andreas
  #6  
Old July 23rd, 2005, 12:32 AM
Mike Wahler
Guest
 
Posts: n/a

re: calling virtual function results in calling function of base class...



"Andreas Lagemann" <andreas.lagemann@freenet.de> wrote in message
news:41e1a2cd$0$27789$9b622d9e@news.freenet.de...[color=blue]
> Mike Wahler schrieb:[color=green]
> > "Andreas Lagemann" <andreas.lagemann@freenet.de> wrote in message
> > news:41e1875a$0$1546$9b622d9e@news.freenet.de...
> >[color=darkred]
> >>Mike Wahler schrieb:
> >>
> >>>"Andreas Lagemann" <andreas.lagemann@freenet.de> wrote in message[/color]
> >
> >[color=darkred]
> >>>Misunderstanding. 'Base::foo()' is being called because you
> >>>supplied a pointer to a 'Base' object. If you want 'Der::foo'
> >>>to be called, you need to suppy the address of (or a reference to)
> >>>a type 'Der' object.
> >>>
> >>
> >>Sorry but as far as I understand, I supplied a pointer (sorry for the
> >>typo) to Der (i.e. &der) when initializing Bogus. Therefore if I call
> >>bogus->bar() Der::foo should be called, shouldn´t it ?[/color]
> >
> >
> > 'bogus' is not a pointer to your base class. It's a pointer
> > to a type 'Bogus' object.
> >[/color]
> Yes, but Bogus has a member of type Base*, which is initialized with a
> pointer to Der.[/color]

That doesn't matter. You were not using that pointer in your
function call.
[color=blue]
>
> Oh I just realized that I made another error defining Bogus::bar().
> It should be
>
> A* Bogus::bar()
> ^^
> {
> ...
> return myBase->foo();
> ^^^^^^
> ...
> }
>
> So any instance of Bogus initialized with a pointer to Der should
> execute Der::foo when Bogus::bar() is called. Is that right ?[/color]

No. The pointer through which you call a virtual function
must be a pointer to the base class. You were not doing that.
[color=blue]
>[color=green]
> >[color=darkred]
> >>Perhaps another Question for clarification:
> >>I want to be able to call a specialized versions of a certain function
> >>without knowing the exact type of specialization at compile time. That
> >>is what I thought virtual functions were intended for ...
> >>
> >>Can please anyone point out, how I could achieve such a behaviour ?[/color]
> >
> >
> > Assign the address of a derived object to a pointer to an object
> > of its base class.
> >
> > #include <iostream>
> >
> > class Base
> > {
> > public:
> > virtual void f() { std::cout << "base\n"; }
> > };
> >
> > class Derived : public Base
> > {
> > public:
> > void f() { std::cout << "derived\n"; }
> > };
> >
> > int main()
> > {
> > base *b1 = new Base;
> > base *b2 = new Derived;
> > b1->f(); /* prints "base" */
> > b2->f(); /* prints "derived" */
> > delete b1;
> > delete b2;
> > return 0;
> > }[/color]
>
> That´s just how I thought it should work. So my example should work the
> same way, doesn´t it ?[/color]

No. Your code does not do the same thing.[color=blue]
>
> Thank you very much for your patience, I´m kinda confused by now ...[/color]

I can tell. :-) I suggest you write a much simpler program first,
until you really understand. I think all that other stuff is
only serving to obscure things.


-Mike


  #7  
Old July 23rd, 2005, 12:34 AM
Howard
Guest
 
Posts: n/a

re: calling virtual function results in calling function of base class...



"Andreas Lagemann" <andreas.lagemann@freenet.de> wrote in message
news:41e1796d$0$30345$9b622d9e@news.freenet.de...[color=blue]
> Hi,
> after browsing FAQ and archive for a while I decided that the following is
> a legal question.
>
> Consider this:
>
> Class Base
> {
> public:
> Base() {}
>
> Base(A* a, B* b);
>
> virtual A* foo(P* p, S& s); // using myA and myB
> protected:
> A* myA;
> B* myB;
> };
>
> class Der : public Base
> {
> public:
> Der(O* o) : Base(), myO(o) {}
> A* foo(P* p; S& s); // not using myA and myB
> private:
> O* myO;
> };
>
> class Bogus
> {
> public:
> Bogus(Base* b) : myBase(b) {}
>
> void bar()
> {
> ...
> myBase->foo(p,s);
> ...
> }
> private:
> Base* myBase;
> };
>
> int main(/*args*/)
> {
> ...
> Der der(someO);
> Bogus* bogus = new Bogus(der);
> ...
> bogus->bar();
> ...
> };
>
> Executing this results in Base::foo being called instead of Der::foo (what
> I would expect) ....
> What am I doing wrong ?
> Is that because cstr of Der does not initialize any mebers of Base ?
> How could I possibly avoid that or get the behaviour I need ?
> Pleas help!!!
>
> Regards,
>
> Andreas Lagemann[/color]

Looks like things are a bit muddled here? :-)

What you're trying to do *should* work. If you have a class that has a
Base* pointer, and you initialize that pointer with the address of a Der
object, then when that class (Bogus) calls a virtual function using its
Base* pointer, it will resolve to the correct call in the Der class.

So, something is wrong with what you've shown.

As Mike suggests, try a simpler example first to be sure you know what is
happenning. Then you can implement it in a more complex environment.

(One other thing: if you're using VisualC++ 6, upgrade to 7. VC++ 6 is not
very standard-compliant. I don't know in which areas exactly, but it's
*possible* this could be one of them...?)

-Howard



  #8  
Old July 23rd, 2005, 12:34 AM
Howard
Guest
 
Posts: n/a

re: calling virtual function results in calling function of base class...



"Andreas Lagemann" <andreas.lagemann@freenet.de> wrote in message
news:41e1796d$0$30345$9b622d9e@news.freenet.de...[color=blue]
> Hi,
> after browsing FAQ and archive for a while I decided that the following is
> a legal question.
>
> Consider this:
>
> Class Base
> {
> public:
> Base() {}
>
> Base(A* a, B* b);
>
> virtual A* foo(P* p, S& s); // using myA and myB
> protected:
> A* myA;
> B* myB;
> };
>
> class Der : public Base
> {
> public:
> Der(O* o) : Base(), myO(o) {}
> A* foo(P* p; S& s); // not using myA and myB
> private:
> O* myO;
> };
>
> class Bogus
> {
> public:
> Bogus(Base* b) : myBase(b) {}
>
> void bar()
> {
> ...
> myBase->foo(p,s);
> ...
> }
> private:
> Base* myBase;
> };
>
> int main(/*args*/)
> {
> ...
> Der der(someO);
> Bogus* bogus = new Bogus(der);
> ...
> bogus->bar();
> ...
> };
>
> Executing this results in Base::foo being called instead of Der::foo (what
> I would expect) ....
> What am I doing wrong ?
> Is that because cstr of Der does not initialize any mebers of Base ?
> How could I possibly avoid that or get the behaviour I need ?
> Pleas help!!!
>
> Regards,
>
> Andreas Lagemann[/color]

Looks like things are a bit muddled here? :-)

What you're trying to do *should* work. If you have a class that has a
Base* pointer, and you initialize that pointer with the address of a Der
object, then when that class (Bogus) calls a virtual function using its
Base* pointer, it will resolve to the correct call in the Der class.

So, something is wrong with what you've shown.

As Mike suggests, try a simpler example first to be sure you know what is
happenning. Then you can implement it in a more complex environment.

(One other thing: if you're using VisualC++ 6, upgrade to 7. VC++ 6 is not
very standard-compliant. I don't know in which areas exactly, but it's
*possible* this could be one of them...?)

-Howard




  #9  
Old July 23rd, 2005, 12:34 AM
Mike Wahler
Guest
 
Posts: n/a

re: calling virtual function results in calling function of base class...


"Howard" <alicebt@hotmail.com> wrote in message
news:VMDEd.97835$uM5.43698@bgtnsc05-news.ops.worldnet.att.net...[color=blue]
> (One other thing: if you're using VisualC++ 6, upgrade to 7. VC++ 6 is[/color]
not[color=blue]
> very standard-compliant. I don't know in which areas exactly, but it's
> *possible* this could be one of them...?)[/color]

FWIW:
One of the compilers I use is VC++v6.0 (SP6), and it handles
polymorphism just fine.

-Mike


Closed Thread


Similar Threads
Thread Thread Starter Forum Replies Last Post
Integrating an explicit function of x from a to b Protoman answers 7 July 6th, 2007 11:45 PM
Pure Virtual Function Calls pakis answers 6 November 17th, 2005 04:36 PM
calling virtual function results in calling function of base class ... tiwy answers 0 July 23rd, 2005 12:32 AM
Initialization of virtual function table pointer DaKoadMunky answers 4 July 22nd, 2005 11:23 AM