Virtual operator overloads don't seem to work?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Stuart Brockman

    Virtual operator overloads don't seem to work?

    Hi,
    I don't quite get what is going on in this code example:

    ---------------------------
    #include <iostream>

    using namespace std;

    class Base{
    public:
    virtual void Test(){
    cout << "Base" << endl;
    }

    virtual bool operator==(cons t Base &other){
    cout << "Base Comparison" << endl;
    return false;
    }
    };

    class Derived : public Base{
    public:
    void Test(){
    cout << "Derived" << endl;
    }

    bool operator==(cons t Derived &other){
    cout << "Derived Comparison" << endl;
    return true;
    }
    };

    int main(int argc, char** argv) {
    Base a; //Create a base object
    a.Test(); //Outputs "Base" as expected
    Derived b, c; //Create two derived objects
    b.Test(); //Outputs "Derived" as expected
    if(b==c) cout << "True" << endl; //Does derived comparison and
    returns true as expected.
    Base *d=&b, *e=&c; //Create two base pointers to derived objects
    d->Test(); //Outputs "Derived" as expected
    if(*d==*e) cout << "True" << endl; //Does base comparison and
    returns false!?
    return 0;
    }
    ----------------------------
    The output is:

    Base
    Derived
    Derived Comparison
    True
    Derived
    Base Comparison

    Notice, that the line "d->Test()" works correctly, but the comparison
    on the next line does not. The compiler (g++ (GCC) 4.2.3 (Ubuntu
    4.2.3-2ubuntu7) ) seems to be ignoring the virtual-ness of
    Base::operator= = . Is this correct? Have I made a mistake?
  • James Kanze

    #2
    Re: Virtual operator overloads don't seem to work?

    On Oct 23, 12:09 am, Stuart Brockman <stuartbrock... @gmail.comwrote :
    I don't quite get what is going on in this code example:
    ---------------------------
    #include <iostream>
    using namespace std;
    class Base{
    public:
    virtual void Test(){
    cout << "Base" << endl;
    }
    virtual bool operator==(cons t Base &other){
    cout << "Base Comparison" << endl;
    return false;
    }
    };
    class Derived : public Base{
    public:
    void Test(){
    cout << "Derived" << endl;
    }
    bool operator==(cons t Derived &other){
    cout << "Derived Comparison" << endl;
    return true;
    }
    };
    int main(int argc, char** argv) {
    Base a; //Create a base object
    a.Test(); //Outputs "Base" as expected
    Derived b, c; //Create two derived objects
    b.Test(); //Outputs "Derived" as expected
    if(b==c) cout << "True" << endl; //Does derived comparison and
    returns true as expected.
    Base *d=&b, *e=&c; //Create two base pointers to derived objects
    d->Test(); //Outputs "Derived" as expected
    if(*d==*e) cout << "True" << endl; //Does base comparison and
    returns false!?
    return 0;}
    ----------------------------
    The output is:
    Base
    Derived
    Derived Comparison
    True
    Derived
    Base Comparison
    Notice, that the line "d->Test()" works correctly, but the
    comparison on the next line does not. The compiler (g++ (GCC)
    4.2.3 (Ubuntu 4.2.3-2ubuntu7) ) seems to be ignoring the
    virtual-ness of Base::operator= = . Is this correct? Have I
    made a mistake?
    How could it do otherwise? Base::operator= =() has a different
    signature than Derived::operat or==(), so the function in the
    derived class hides, rather than overloads, the function in the
    base class. Moreover, there's no way you could possibly call
    Derived::operat or==(), since it requires a Derived const&, and
    can't be called with a Base const& (which is basically what you
    get when you dereference a Base const*).

    In general, binary operators don't work very well with
    inheritance; what you'd really need to make them work is double
    dispatch. In the special case of == and !=, you can do
    something like:

    bool
    Derived::operat or==( Base const& other ) const
    {
    Derived const* p
    = dynamic_cast< Derived const* >( &other ) ;
    return p != NULL && operator==( *p ) ;
    }

    in addition to your normal Derived::operat or==, at least if you
    decide that two different derived types can never compare equal.
    If it makes sense for two different derived types to compare
    equal, however (say because they both represent the same value,
    but in different ways), you'll need to set up a much more
    complicated mechanism.

    --
    James Kanze (GABI Software) email:james.kan ze@gmail.com
    Conseils en informatique orientée objet/
    Beratung in objektorientier ter Datenverarbeitu ng
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

    Comment

    Working...