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

  • Thread starter Andreas Lagemann
  • Start date
A

Andreas Lagemann

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
 
M

Mike Wahler

Andreas Lagemann said:
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);

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

None of types 'A', 'P', or 'S' have been declared
at this point.
protected:
A* myA;
B* myB;
};

class Der : public Base
{
public:
Der(O* o) :

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

None of the types 'A', 'P', or 'S' have been declared
at this point.
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 ?

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.
Is that because cstr of Der does not initialize any mebers of Base ?
No.

How could I possibly avoid that or get the behaviour I need ?


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
 
A

Andreas Lagemann

Mike said:
This won't compile because types 'A' and 'B' have
not been declared at this point.




None of types 'A', 'P', or 'S' have been declared
at this point.
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.
This will happen automatically, you need not specify it.
I know that, I just wanted to stress the fact that I call the std. cstr
at that point.
None of the types 'A', 'P', or 'S' have been declared
at this point.
see above

[edit] Bogus* bogus = new Bogus(&der);
^^^^
that was what I meant ...
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 ?
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.

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
 
M

Mike Wahler

Andreas Lagemann said:
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 ?

'bogus' is not a pointer to your base class. It's a pointer
to a type 'Bogus' object.
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 ?

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
 
A

Andreas Lagemann

Mike said:
'bogus' is not a pointer to your base class. It's a pointer
to a type 'Bogus' object.
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 ?
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;
}

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
 
M

Mike Wahler

Andreas Lagemann said:
Yes, but Bogus has a member of type Base*, which is initialized with a
pointer to Der.

That doesn't matter. You were not using that pointer in your
function call.
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 ?

No. The pointer through which you call a virtual function
must be a pointer to the base class. You were not doing that.
That´s just how I thought it should work. So my example should work the
same way, doesn´t it ?

No. Your code does not do the same thing.
Thank you very much for your patience, I´m kinda confused by now ...

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
 
H

Howard

Andreas Lagemann said:
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

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
 
H

Howard

Andreas Lagemann said:
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

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
 
M

Mike Wahler

Howard said:
(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...?)

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

-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

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top