Variant return type

Discussion in 'C++' started by C++, Nov 27, 2005.

  1. C++

    C++ Guest

    According to Thinking in C++
    "You cannot modify the return type of a virtual function during
    overriding.but there is a special case in which you can slightly
    modify the return type. If you¡¯re returning a pointer or a reference to a
    base class, then the overridden version of the function may
    return a pointer or reference to a class derived from what the base
    returns." And here's the example:

    class PetFood
    {
    public:
    virtual string foodType() const = 0;
    };

    class Pet
    {
    public:
    virtual string type() const = 0;
    virtual PetFood* eats() = 0;
    };

    class Bird : public Pet
    {
    public:
    string type() const { return "Bird"; }
    class BirdFood : public PetFood
    {
    public:
    string foodType() const
    {
    return "Bird food";
    }
    };

    // Upcast to base type:
    PetFood* eats() { return &bf; }
    private:
    BirdFood bf;
    };

    class Cat : public Pet
    {
    public:
    string type() const { return "Cat"; }
    class CatFood : public PetFood
    {
    public:
    string foodType() const { return "Birds"; }
    };
    // Return exact type instead:
    CatFood* eats() { return &cf; }
    private:
    CatFood cf;
    };

    int main()
    {
    Bird b;
    Cat c;
    Pet* p[] = { &b, &c, };
    for(int i = 0; i < sizeof p / sizeof *p; i++)
    cout << p->type() << " eats "
    << p->eats()->foodType() << endl;
    // Can return the exact type:
    Cat::CatFood* cf = c.eats();
    Bird::BirdFood* bf;
    // Cannot return the exact type:
    //! bf = b.eats();
    // Must downcast:
    bf = dynamic_cast<Bird::BirdFood*>(b.eats());
    }

    What annoying me is that once I get code above compiled, I get a compiler
    error saying
    "overriding virtual function differs from 'Pet::eats' only by return type or
    calling convention" which is for "CatFood* eats() { return &cf; }"
    But this differ is author's intension, How's that was flagged as an error?
     
    C++, Nov 27, 2005
    #1
    1. Advertising

  2. C++ wrote:
    > What annoying me is that once I get code above compiled, I get a compiler
    > error saying
    > "overriding virtual function differs from 'Pet::eats' only by return type or
    > calling convention" which is for "CatFood* eats() { return &cf; }"
    > But this differ is author's intension, How's that was flagged as an error?


    Compiles well on g++3.4.2 and also on Comeau online.
    Probably your compiler might have a bug.
     
    Neelesh Bodas, Nov 27, 2005
    #2
    1. Advertising

  3. * C++:
    > According to Thinking in C++
    > "You cannot modify the return type of a virtual function during
    > overriding.but there is a special case in which you can slightly
    > modify the return type. If you¡¯re returning a pointer or a reference to a
    > base class, then the overridden version of the function may
    > return a pointer or reference to a class derived from what the base
    > returns." And here's the example:
    >
    > class PetFood
    > {
    > public:
    > virtual string foodType() const = 0;
    > };
    >
    > class Pet
    > {
    > public:
    > virtual string type() const = 0;
    > virtual PetFood* eats() = 0;
    > };
    >
    > class Bird : public Pet
    > {
    > public:
    > string type() const { return "Bird"; }
    > class BirdFood : public PetFood
    > {
    > public:
    > string foodType() const
    > {
    > return "Bird food";
    > }
    > };
    >
    > // Upcast to base type:
    > PetFood* eats() { return &bf; }
    > private:
    > BirdFood bf;
    > };
    >
    > class Cat : public Pet
    > {
    > public:
    > string type() const { return "Cat"; }
    > class CatFood : public PetFood
    > {
    > public:
    > string foodType() const { return "Birds"; }
    > };
    > // Return exact type instead:
    > CatFood* eats() { return &cf; }
    > private:
    > CatFood cf;
    > };
    >
    > int main()
    > {
    > Bird b;
    > Cat c;
    > Pet* p[] = { &b, &c, };
    > for(int i = 0; i < sizeof p / sizeof *p; i++)
    > cout << p->type() << " eats "
    > << p->eats()->foodType() << endl;
    > // Can return the exact type:
    > Cat::CatFood* cf = c.eats();
    > Bird::BirdFood* bf;
    > // Cannot return the exact type:
    > //! bf = b.eats();
    > // Must downcast:
    > bf = dynamic_cast<Bird::BirdFood*>(b.eats());
    > }
    >
    > What annoying me is that once I get code above compiled, I get a compiler
    > error saying
    > "overriding virtual function differs from 'Pet::eats' only by return type or
    > calling convention" which is for "CatFood* eats() { return &cf; }"
    > But this differ is author's intension, How's that was flagged as an error?


    It means you're using an old compiler.

    FAQ item 20.8 (as the numbering is right now) describes covariant return
    types, <url:
    http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.8>.

    Section 1.5.3 of
    <url:
    http://home.no.net/dubjai/win32cpptut/special/pointers/preview/pointers_01_beta.doc.pdf>
    describes a workaround for older compilers such as (presumably) yours,
    as well as discussing the issues in more detail & generality.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Nov 27, 2005
    #3
  4. C++

    Guest

    C++ wrote:

    > According to Thinking in C++
    > "You cannot modify the return type of a virtual function during
    > overriding.but there is a special case in which you can slightly
    > modify the return type. If you¡¯re returning a pointer or a reference to a
    > base class, then the overridden version of the function may
    > return a pointer or reference to a class derived from what the base
    > returns." And here's the example:
    >
    > class PetFood
    > {
    > public:
    > virtual string foodType() const = 0;
    > };
    >
    > class Pet
    > {
    > public:
    > virtual string type() const = 0;
    > virtual PetFood* eats() = 0;
    > };
    >
    > class Bird : public Pet
    > {
    > public:
    > string type() const { return "Bird"; }
    > class BirdFood : public PetFood
    > {
    > public:
    > string foodType() const
    > {
    > return "Bird food";
    > }
    > };
    >
    > // Upcast to base type:
    > PetFood* eats() { return &bf; }
    > private:
    > BirdFood bf;
    > };
    >
    > class Cat : public Pet
    > {
    > public:
    > string type() const { return "Cat"; }
    > class CatFood : public PetFood
    > {
    > public:
    > string foodType() const { return "Birds"; }
    > };
    > // Return exact type instead:
    > CatFood* eats() { return &cf; }
    > private:
    > CatFood cf;
    > };
    >
    > int main()
    > {
    > Bird b;
    > Cat c;
    > Pet* p[] = { &b, &c, };
    > for(int i = 0; i < sizeof p / sizeof *p; i++)
    > cout << p->type() << " eats "
    > << p->eats()->foodType() << endl;
    > // Can return the exact type:
    > Cat::CatFood* cf = c.eats();
    > Bird::BirdFood* bf;
    > // Cannot return the exact type:
    > //! bf = b.eats();
    > // Must downcast:
    > bf = dynamic_cast<Bird::BirdFood*>(b.eats());
    > }
    >
    > What annoying me is that once I get code above compiled, I get a compiler
    > error saying
    > "overriding virtual function differs from 'Pet::eats' only by return type or
    > calling convention" which is for "CatFood* eats() { return &cf; }"
    > But this differ is author's intension, How's that was flagged as an error?


    What compiler are you using? Comeau online compiles your code fine if I
    add

    #include <iostream>
    #include <string>
    using namespace std;

    at the beginning. If you are using an old compiler you may have the
    problem described here:

    http://www.parashift.com/c -faq-lite/virtual-functions.html#faq-20.8

    Gavin Deane
     
    , Nov 27, 2005
    #4
    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.
Similar Threads
  1. romi
    Replies:
    1
    Views:
    2,617
    Alf P. Steinbach
    Sep 2, 2004
  2. christopher diggins

    Sharing code for a variant style type

    christopher diggins, Jan 4, 2005, in forum: C++
    Replies:
    3
    Views:
    485
  3. romi
    Replies:
    2
    Views:
    660
    Joona I Palaste
    Sep 2, 2004
  4. Claus77

    VARIANT type

    Claus77, Oct 23, 2006, in forum: C++
    Replies:
    4
    Views:
    1,046
    Claus77
    Oct 24, 2006
  5. rkbnair

    How can I define type variant in c#?

    rkbnair, Jan 7, 2008, in forum: ASP .Net
    Replies:
    4
    Views:
    30,509
    rkbnair
    Jan 7, 2008
Loading...

Share This Page