CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5
  1. #1
    Join Date
    Oct 2009
    Posts
    7

    Covariant return types and virtual function

    As I understand, below code wont compile due to definition of covariant return type (it has to be reference or pointer).
    But If I just remove 'virtual' keyword then it compiles(and runs).
    Any thoughts why it compiles even when the return type is not pointer or reference(when base fun is non-virtual)?
    And why it fails when base fun is virtual?

    Thanks for your time.
    -Sachin

    #include <stdio.h>
    #include <conio.h>
    #include <iostream>

    using namespace std;

    class A
    {
    public:
    virtual A fun()
    {
    cout<<"A fun\n";
    return *this;
    }

    };
    class B: public A
    {
    public:
    B fun()
    {
    cout<<"B fun"<<endl;
    return *this;
    }
    };
    int main()
    {
    B obj;
    A *ptr = &obj;

    obj.fun();
    ptr->fun();
    getch();
    return 0;
    }

  2. #2
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401

    Re: Covariant return types and virtual function

    Without the "virtual" keyword A::fun and B::fun don't have anything to do with each other. They are two separate functions who just happen to have the same name. The compiler simply does not care about them having different return types.

    If the functions are virtual, the return type has to be a pointer or reference to avoid truncation of the object to take place. In your example, B::fun() would return a B object which would then immediately be converted to an A object and all information that would make it a B object would be lost. In term, it does not make sense for the function to return a B object in the first place.
    More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. --W.A.Wulf

    Premature optimization is the root of all evil --Donald E. Knuth


    Please read Information on posting before posting, especially the info on using [code] tags.

  3. #3
    Join Date
    Oct 2009
    Posts
    7

    Re: Covariant return types and virtual function

    Thanks for the reply. That explains me correctly.
    So I guess we can say, the child class is hiding the fun in parent class, right?

    Regarding the 'truncation' - whats happening in below code? Is there any flaw?
    I am getting expected output - is it just by chance?

    class A
    {
    public:
    A fun()
    {
    cout<<"A fun\n";
    return *this;
    }

    };
    class B: public A
    {
    public:
    B fun()
    {
    cout<<"B fun"<<endl;
    return *this;
    }
    void test_fun()
    {
    cout<<"B's Test fun"<<endl;
    }
    };
    int main()
    {
    B obj;
    A *ptr = &obj;

    B* ptr1 = (B *)&(ptr->fun());
    ptr1->test_fun();
    getch();
    return 0;
    }

    Regards,
    -Sachin

  4. #4
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: Covariant return types and virtual function

    Quote Originally Posted by sachhi99 View Post
    Thanks for the reply. That explains me correctly.
    So I guess we can say, the child class is hiding the fun in parent class, right?

    Regarding the 'truncation' - whats happening in below code? Is there any flaw?
    I am getting expected output - is it just by chance?

    class A
    {
    public:
    A fun()
    {
    cout<<"A fun\n";
    return *this;
    }

    };
    class B: public A
    {
    public:
    B fun()
    {
    cout<<"B fun"<<endl;
    return *this;
    }
    void test_fun()
    {
    cout<<"B's Test fun"<<endl;
    }
    };
    int main()
    {
    B obj;
    A *ptr = &obj;

    B* ptr1 = (B *)&(ptr->fun());
    ptr1->test_fun();
    getch();
    return 0;
    }

    Regards,
    -Sachin
    Depends what you mean by "expected". In my opinion, you aren't getting expected output.

    Code:
    int main()
    {
        B obj;
        A *ptr = &obj;
        ptr->fun();
    }
    This says "A fun" when the pointer is clearly pointing to a B object. Is this the behavior you want?
    In your case, there is no slicing, because your classes are not virtual, but you have a bigger problem of reference to temporary...

  5. #5
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401

    Re: Covariant return types and virtual function

    Please start using code tags for your code. Read the FAQ!
    Code:
        B* ptr1 = (B *)&(ptr->fun());
    The behaviour of your program after this line is undefined. ptr->fun() returns an A object. As not every A is a B, assuming that it is, will result in undefined behaviour.

    In your case, this will work as your classes don't have data members. Even if they did, there are chances that it will work as you expect (this is part of "undefined behaviour"). But you will never know if it works all the time or if you run it on a different platform or compile it with a different compiler.
    Last edited by treuss; November 2nd, 2009 at 10:23 AM.
    More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. --W.A.Wulf

    Premature optimization is the root of all evil --Donald E. Knuth


    Please read Information on posting before posting, especially the info on using [code] tags.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured