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

Discussion in 'C++' started by Andreas Lagemann, Jan 9, 2005.

  1. 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
     
    Andreas Lagemann, Jan 9, 2005
    #1
    1. Advertising

  2. Andreas Lagemann

    Mike Wahler Guest

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

    "Andreas Lagemann" <> wrote in message
    news:41e1796d$0$30345$...
    > 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
     
    Mike Wahler, Jan 9, 2005
    #2
    1. Advertising

  3. Re: calling virtual function results in calling function of baseclass ...

    Mike Wahler schrieb:
    > "Andreas Lagemann" <> wrote in message
    > news:41e1796d$0$30345$...
    >
    >>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
     
    Andreas Lagemann, Jan 9, 2005
    #3
  4. Andreas Lagemann

    Mike Wahler Guest

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

    "Andreas Lagemann" <> wrote in message
    news:41e1875a$0$1546$...
    > Mike Wahler schrieb:
    > > "Andreas Lagemann" <> 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
     
    Mike Wahler, Jan 9, 2005
    #4
  5. Re: calling virtual function results in calling function of baseclass ...

    Mike Wahler schrieb:
    > "Andreas Lagemann" <> wrote in message
    > news:41e1875a$0$1546$...
    >
    >>Mike Wahler schrieb:
    >>
    >>>"Andreas Lagemann" <> 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
     
    Andreas Lagemann, Jan 9, 2005
    #5
  6. Andreas Lagemann

    Mike Wahler Guest

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

    "Andreas Lagemann" <> wrote in message
    news:41e1a2cd$0$27789$...
    > Mike Wahler schrieb:
    > > "Andreas Lagemann" <> wrote in message
    > > news:41e1875a$0$1546$...
    > >
    > >>Mike Wahler schrieb:
    > >>
    > >>>"Andreas Lagemann" <> 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
     
    Mike Wahler, Jan 9, 2005
    #6
  7. Andreas Lagemann

    Howard Guest

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

    "Andreas Lagemann" <> wrote in message
    news:41e1796d$0$30345$...
    > 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
     
    Howard, Jan 10, 2005
    #7
  8. Andreas Lagemann

    Howard Guest

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

    "Andreas Lagemann" <> wrote in message
    news:41e1796d$0$30345$...
    > 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
     
    Howard, Jan 10, 2005
    #8
  9. Andreas Lagemann

    Mike Wahler Guest

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

    "Howard" <> wrote in message
    news:VMDEd.97835$...
    > (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
     
    Mike Wahler, Jan 10, 2005
    #9
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page