virtual assignment operator/polymorphism question

Discussion in 'C++' started by sven.bauer@gmail.com, Apr 12, 2007.

  1. Guest

    Hi,

    I have a question following up the following slightly older posting:
    http://groups.google.de/group/comp.lang.c /browse_thread/thread/40e52371e89806ae/52a3a6551f84d38b

    class Base
    {
    virtual Base& operator = (const Base &k) {}
    };


    class Derived: public Base
    {
    virtual Base& operator = (const Base &k) {}
    };


    int main(int argc, char* argv[])
    {
    Derived *dp1 = new Derived();
    Derived *dp2 = new Derived();

    *dp1 = *dp2; // Base::eek:perator= is called

    Base *bp = *dp1;

    *bp = *dp2; // Derived::eek:perator= is called

    return 0;
    }

    While it seems clear to me why *bp = *dp2 leads to the
    Derived::eek:perator= being called I do not understand why *dp1 = *dp2
    calls the Base::eek:perator=.
    What's going on here???

    Thanks!

    Sven
    , Apr 12, 2007
    #1
    1. Advertising

  2. wrote:
    > Hi,
    >
    > I have a question following up the following slightly older posting:
    > http://groups.google.de/group/comp.lang.c /browse_thread/thread/40e52371e89806ae/52a3a6551f84d38b
    >
    > class Base
    > {
    > virtual Base& operator = (const Base &k) {}
    > };
    >
    >
    > class Derived: public Base
    > {
    > virtual Base& operator = (const Base &k) {}
    > };
    >
    >
    > int main(int argc, char* argv[])
    > {
    > Derived *dp1 = new Derived();
    > Derived *dp2 = new Derived();
    >
    > *dp1 = *dp2; // Base::eek:perator= is called
    >
    > Base *bp = *dp1;
    >
    > *bp = *dp2; // Derived::eek:perator= is called
    >
    > return 0;
    > }
    >
    > While it seems clear to me why *bp = *dp2 leads to the
    > Derived::eek:perator= being called I do not understand why *dp1 = *dp2
    > calls the Base::eek:perator=.
    > What's going on here???


    *dp1 = *dp2; calls the compiler supplied operator = i.e.

    Derived & operator = (const Derived & k)

    The compiler supplied Derived::eek:perator = calls Base::eek:perator=
    statically, not dynamically. Hence, it appears you're calling
    Base& operator = (const Base &k), but you're not really.


    Next time, please post code that compiles.

    #include <iostream>

    class Base
    {
    public:
    virtual Base& operator = (const Base &k)
    {
    std::cout << "Base\n"; return *this;
    }
    };


    class Derived: public Base
    {
    public:
    virtual Derived& operator = (const Base &k)
    {
    std::cout << "Derived\n"; return *this;
    }

    Derived& operator = (const Derived &k)
    {
    ( * static_cast<Base *>( this ) ) = k;
    return *this;
    }
    };


    int main(int argc, char* argv[])
    {
    Derived *dp1 = new Derived();
    Derived *dp2 = new Derived();

    *dp1 = *dp2; // Base::eek:perator= is called
    // Derived & operator = (const Derived &k);

    Base *bp = dp1;

    *bp = *dp2; // Derived::eek:perator= is called

    return 0;
    }
    Gianni Mariani, Apr 12, 2007
    #2
    1. Advertising

  3. James Kanze Guest

    On Apr 12, 1:15 pm, wrote:

    > I have a question following up the following slightly older
    > posting:http://groups.google.de/group/comp.lang.c /browse_thread/thread/40e5...


    > class Base
    > {
    > virtual Base& operator = (const Base &k) {}
    > };


    > class Derived: public Base
    > {
    > virtual Base& operator = (const Base &k) {}
    > };


    > int main(int argc, char* argv[])
    > {
    > Derived *dp1 = new Derived();
    > Derived *dp2 = new Derived();


    > *dp1 = *dp2; // Base::eek:perator= is called


    How do you know? I think rather that the compiler generated
    derived operator is being called (statically, since it isn't
    virtual). This operator, of course, calls the base operator=.

    > Base *bp = *dp1;
    > *bp = *dp2; // Derived::eek:perator= is called


    Yes, but not the default Derived::eek:perator=.

    > return 0;
    > }


    > While it seems clear to me why *bp = *dp2 leads to the
    > Derived::eek:perator= being called I do not understand why *dp1 = *dp2
    > calls the Base::eek:perator=.
    > What's going on here???


    Your Derived::eek:perator= is not a copy assignment operator (since
    it doesn't assign a Derived to Derived, but a Base to Derived),
    so it doesn't inhibit the compiler from generating its version.

    More generally, polymorphism and assignment don't work well
    together. If you plan on using a class as a base, it's
    generally best to declare the operator= private, and not
    implement it (or to derive it from something like
    boost::noncopyable).

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Apr 13, 2007
    #3
    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. Stephan Kurpjuweit
    Replies:
    3
    Views:
    3,583
    Andrey Tarasevich
    Jun 14, 2004
  2. N4M
    Replies:
    17
    Views:
    609
    Daniel T.
    Aug 19, 2004
  3. Krivenok Dmitry
    Replies:
    13
    Views:
    1,382
    Axter
    Jun 1, 2006
  4. Chris
    Replies:
    34
    Views:
    1,472
  5. sukhpal
    Replies:
    5
    Views:
    348
    James Kanze
    Feb 9, 2009
Loading...

Share This Page