469,286 Members | 2,500 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,286 developers. It's quick & easy.

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

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
Jul 22 '05 #1
8 1406

"Andreas Lagemann" <an**************@freenet.de> wrote in message
news:41***********************@news.freenet.de...
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) : Base(),
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
Jul 22 '05 #2
Mike Wahler schrieb:
"Andreas Lagemann" <an**************@freenet.de> wrote in message
news:41***********************@news.freenet.de...
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.

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.
protected:
A* myA;
B* myB;
};

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


Base(),

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.
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.

see above
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);

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

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 ?
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.


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
Jul 22 '05 #3

"Andreas Lagemann" <an**************@freenet.de> wrote in message
news:41**********************@news.freenet.de...
Mike Wahler schrieb:
"Andreas Lagemann" <an**************@freenet.de> wrote in message 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 ?


'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
Jul 22 '05 #4
Mike Wahler schrieb:
"Andreas Lagemann" <an**************@freenet.de> wrote in message
news:41**********************@news.freenet.de...
Mike Wahler schrieb:
"Andreas Lagemann" <an**************@freenet.de> wrote in message
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 ?

'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 ?
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;
}


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
Jul 22 '05 #5

"Andreas Lagemann" <an**************@freenet.de> wrote in message
news:41***********************@news.freenet.de...
Mike Wahler schrieb:
"Andreas Lagemann" <an**************@freenet.de> wrote in message
news:41**********************@news.freenet.de...
Mike Wahler schrieb:

"Andreas Lagemann" <an**************@freenet.de> wrote in message
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 ?

'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.


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.
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;
}


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
Jul 22 '05 #6

"Andreas Lagemann" <an**************@freenet.de> wrote in message
news:41***********************@news.freenet.de...
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

Jul 22 '05 #7

"Andreas Lagemann" <an**************@freenet.de> wrote in message
news:41***********************@news.freenet.de...
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


Jul 22 '05 #8
"Howard" <al*****@hotmail.com> wrote in message
news:VM*******************@bgtnsc05-news.ops.worldnet.att.net...
(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
Jul 22 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

14 posts views Thread by mshetty | last post: by
12 posts views Thread by Peter Cranz | last post: by
3 posts views Thread by Klaas Vantournhout | last post: by
7 posts views Thread by sam_cit | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by suresh191 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.