is operator= not polimorphic (virtual)?

Discussion in 'C++' started by Heiner, Oct 8, 2005.

  1. Heiner

    Heiner Guest

    #include <stdio.h>

    class A
    {
    public:
    virtual A & operator= (const A &);
    virtual void test(const A &);
    };

    class B : public A
    {
    public:
    virtual A & operator= (const A &);
    virtual void test(const A &);
    };

    A & A::eek:perator= (const A & src)
    {
    printf("A= called\n");
    return * this;
    }

    void A::test(const A & src)
    {
    printf("A::test called\n");
    }

    A & B::eek:perator= (const A & src)
    {
    printf("B= called\n");
    return * this;
    }

    void B::test(const A & src)
    {
    printf("B::test called\n");
    }

    int main (int)
    {
    A a;
    B b1, b2;
    printf("b1 = a: "); b1 = a;
    printf("b1 = b2: "); b1 = b2;
    printf("b1.test(a): "); b1.test(a);
    printf("b1.test(b2): "); b1.test(b2);
    return 0;
    }

    I would have guessed, that b1 = b2 calls B::eek:perator=, as b1.test(b2)
    calls B::test. But what I get is:

    7of9# gmake && ./test
    g++ main.cpp -o test
    b1 = a: B= called
    b1 = b2: A= called
    b1.test(a): B::test called
    b1.test(b2): B::test called
    7of9# g++ --version
    g++ (GCC) 3.4.2 [FreeBSD] 20040728
    Copyright (C) 2004 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions. There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

    Is operator= not polymorphic?


    Heiner

    Remove the nospam to get my real address
     
    Heiner, Oct 8, 2005
    #1
    1. Advertising

  2. Heiner

    Markus Moll Guest

    Heiner wrote:

    > #include <stdio.h>
    >
    > class A
    > {
    > public:
    > virtual A & operator= (const A &);
    > virtual void test(const A &);
    > };
    >
    > class B : public A
    > {
    > public:
    > virtual A & operator= (const A &);
    > virtual void test(const A &);
    > };

    [...]
    > I would have guessed, that b1 = b2 calls B::eek:perator=, as b1.test(b2)
    > calls B::test. But what I get is:

    [...]
    > b1 = a: B= called
    > b1 = b2: A= called
    > b1.test(a): B::test called
    > b1.test(b2): B::test called

    [...]
    > Is operator= not polymorphic?


    Yes, but...
    There is more than one operator= involved, and that is your problem.
    You do not provide a default assignment operator for class B, so the
    compiler generates one with signature operator=(const B&);
    This assignment operator works by assigning base classes and members
    individually, thus invoking A::eek:perator=(const A&). This produces the
    output you observe.

    What exactly do you want to do?

    Markus
     
    Markus Moll, Oct 8, 2005
    #2
    1. Advertising

  3. Heiner

    Heinz Ozwirk Guest

    "Heiner" <> schrieb im Newsbeitrag
    news:p...
    >
    > #include <stdio.h>
    >
    > class A
    > {
    > public:
    > virtual A & operator= (const A &);
    > virtual void test(const A &);
    > };
    >
    > class B : public A
    > {
    > public:
    > virtual A & operator= (const A &);
    > virtual void test(const A &);
    > };
    >
    > A & A::eek:perator= (const A & src)
    > {
    > printf("A= called\n");
    > return * this;
    > }
    >
    > void A::test(const A & src)
    > {
    > printf("A::test called\n");
    > }
    >
    > A & B::eek:perator= (const A & src)
    > {
    > printf("B= called\n");
    > return * this;
    > }
    >
    > void B::test(const A & src)
    > {
    > printf("B::test called\n");
    > }
    >
    > int main (int)
    > {
    > A a;
    > B b1, b2;
    > printf("b1 = a: "); b1 = a;
    > printf("b1 = b2: "); b1 = b2;
    > printf("b1.test(a): "); b1.test(a);
    > printf("b1.test(b2): "); b1.test(b2);
    > return 0;
    > }
    >
    > I would have guessed, that b1 = b2 calls B::eek:perator=, as b1.test(b2)
    > calls B::test. But what I get is:
    >
    > 7of9# gmake && ./test
    > g++ main.cpp -o test
    > b1 = a: B= called
    > b1 = b2: A= called
    > b1.test(a): B::test called
    > b1.test(b2): B::test called
    > 7of9# g++ --version
    > g++ (GCC) 3.4.2 [FreeBSD] 20040728
    > Copyright (C) 2004 Free Software Foundation, Inc.
    > This is free software; see the source for copying conditions. There is NO
    > warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
    > PURPOSE.
    >
    > Is operator= not polymorphic?


    Polymorphism doesn't matter in this example. Polymorphism only matters when
    functions are called through a pointer or reference to an object, not when
    it is called directly for an object of known type.

    Your guess is wrong because you forgot the compiler supplied assignment
    operator, which is called for b1 = b2, and which in turn calls A's
    (explicit) assignment operator, which prints the message.

    HTH
    Heinz
     
    Heinz Ozwirk, Oct 8, 2005
    #3
  4. Heiner

    Rolf Magnus Guest

    Heiner wrote:

    [...]

    > int main (int)
    > {
    > A a;
    > B b1, b2;
    > printf("b1 = a: "); b1 = a;
    > printf("b1 = b2: "); b1 = b2;


    The above line calls the compiler generated B& B::eek:perator=(const B&), which
    in turn calls the base class's operator=.

    > printf("b1.test(a): "); b1.test(a);
    > printf("b1.test(b2): "); b1.test(b2);
    > return 0;
    > }


    [...]

    > Is operator= not polymorphic?


    It is if you make it virtual (as you did).
     
    Rolf Magnus, Oct 8, 2005
    #4
  5. Heiner

    Heiner Guest

    On Sat, 08 Oct 2005 13:04:34 +0200, Markus Moll wrote:

    > What exactly do you want to do?


    Thanks for both answers. I have a container class AC containing A
    instances. This container can be cloned: it clones all A instances as well
    (by calling A::eek:perator=). Now there are derived classes: BC is
    derived from AC and B from A. Therefore the container BC contains B
    instances (and maybe A instances as well), which can be cloned. I have not
    dublicated the clone code of AC, as I thought virtual operator= will do
    the magic. Actually it didn't. So I changed my code to:

    #include <stdio.h>

    class A
    {
    public:
    virtual A & operator= (const A &);
    };

    class B : public A
    {
    public:
    virtual A & operator= (const A &);
    virtual B & operator= (const B &);
    };

    A & A::eek:perator= (const A & src)
    {
    printf("A= called, ");
    return * this;
    }

    A & B::eek:perator= (const A & src)
    {
    printf("B.1= called, ");
    A::eek:perator=(src);
    const B * srcB = dynamic_cast<const B *>(& src);
    if (srcB)
    printf("B.2= called, ");
    return * this;
    }

    B & B::eek:perator= (const B & src)
    {
    printf("B.3= called, ");
    operator=((const A &)src);
    return * this;
    }

    int main (int)
    {
    A a;
    B b1, b2;
    printf("b1 = a: "); b1 = a;
    printf("\nb1 = b2: "); b1 = b2;
    A* a1 = & b1, *a2 = &b2;
    printf("\n*a1 = *a2: "); *a1 = *a2;
    printf("\n");
    return 0;
    }


    which now gives:

    7of9# gmake && ./test
    g++ main.cpp -o test
    b1 = a: B.1= called, A= called,
    b1 = b2: B.3= called, B.1= called, A= called, B.2= called,
    *a1 = *a2: B.1= called, A= called, B.2= called,

    I think that is how it should be implemented.
    Or is there a dynamic_cast free solution as well?


    Heiner

    Remove the nospam to get my real address
     
    Heiner, Oct 8, 2005
    #5
  6. Heiner

    Fraser Ross Guest

    > class B : public A
    > {
    > public:
    > virtual A & operator= (const A &);
    > virtual void test(const A &);
    > };



    Is there any reason at any time for writing an assignment operator that
    return a reference to a class not of the type the function is within?

    The example appears to show a compiler bug with BCB6.

    Fraser.
     
    Fraser Ross, Oct 8, 2005
    #6
  7. Heiner

    Rolf Magnus Guest

    Heiner wrote:

    > On Sat, 08 Oct 2005 13:04:34 +0200, Markus Moll wrote:
    >
    >> What exactly do you want to do?

    >
    > Thanks for both answers. I have a container class AC containing A
    > instances.


    Instances?

    > This container can be cloned: it clones all A instances as well
    > (by calling A::eek:perator=). Now there are derived classes: BC is
    > derived from AC and B from A. Therefore the container BC contains B
    > instances (and maybe A instances as well), which can be cloned.


    If it stores instances, no polymorphism is involved.

    > I have not dublicated the clone code of AC, as I thought virtual operator=
    > will do the magic. Actually it didn't.


    An object cannot change its class during its life time. So the assignment
    operator cannot transform an A object into a B object.

    > So I changed my code to:
    >
    > #include <stdio.h>
    >
    > class A
    > {
    > public:
    > virtual A & operator= (const A &);
    > };
    >
    > class B : public A
    > {
    > public:
    > virtual A & operator= (const A &);
    > virtual B & operator= (const B &);
    > };
    >
    > A & A::eek:perator= (const A & src)
    > {
    > printf("A= called, ");
    > return * this;
    > }
    >
    > A & B::eek:perator= (const A & src)
    > {
    > printf("B.1= called, ");
    > A::eek:perator=(src);
    > const B * srcB = dynamic_cast<const B *>(& src);
    > if (srcB)
    > printf("B.2= called, ");
    > return * this;
    > }


    So if the object provided on the right hand side is not a B, the assignment
    operator does in fact nothing. So why have that operator at all? It would
    be better to get an error if you try that instead of silently ignoring it.

    > B & B::eek:perator= (const B & src)
    > {
    > printf("B.3= called, ");
    > operator=((const A &)src);
    > return * this;
    > }


    > I think that is how it should be implemented.


    Well, if you want several objects of different types in one container, you
    shouldn't store instances but pointers to them in the container. Then, and
    only then, can you use polymorphism.
     
    Rolf Magnus, Oct 8, 2005
    #7
  8. Heiner

    Heiner Guest

    On Sat, 08 Oct 2005 16:29:01 +0200, Rolf Magnus wrote:

    > Instances?

    I use the term instance for any usage of a class. So A a creates an
    instance and A* a = new A as well. If the term is wrong, sorry.

    Maybe "pointer of reference to an instance" is more correctly

    > Well, if you want several objects of different types in one container, you
    > shouldn't store instances but pointers to them in the container. Then, and
    > only then, can you use polymorphism.


    That's what I wanted to discuss. My container AC contains pointers to
    instances of A, and so do BC with B, while BC derives from AC and B from
    A. A::eek:perator= is virtual, so that the cloning code within AC should work
    for BC instances as well.

    I guess, I know now how to do it. Thanks again.

    Heiner

    Remove the nospam to get my real address
     
    Heiner, Oct 8, 2005
    #8
  9. Heiner

    Heiner Guest

    On Sat, 08 Oct 2005 13:13:53 +0100, Fraser Ross wrote:

    >> class B : public A
    >> {
    >> public:
    >> virtual A & operator= (const A &);
    >> virtual void test(const A &);
    >> };

    >
    >
    > Is there any reason at any time for writing an assignment operator that
    > return a reference to a class not of the type the function is within?


    Yes, see the rest of the discussion. As B derives from A I wanted to
    overwrite A's operator=. Therefore I have to use the same signature.

    > The example appears to show a compiler bug with BCB6.


    Actually it only showed my misunderstanding of C++ default method
    generation. If a class X has no X::eek:perator=(const X &), the compiler
    creates one. That's what happend here. With both operator= defined, my
    example worked (see other posts, please)


    Heiner

    --

    Heiner

    Remove the nospam to get my real address
     
    Heiner, Oct 8, 2005
    #9
  10. Heiner

    Fraser Ross Guest

    > Yes, see the rest of the discussion. As B derives from A I wanted to
    > overwrite A's operator=. Therefore I have to use the same signature.


    You can't overload with a different return type alone and therefore you
    can override with a different return type alone. I think you have an
    unwanted way of writing a return type for assignment operators. Noone
    has given any reason for writing them as such yet.

    Fraser.
     
    Fraser Ross, Oct 8, 2005
    #10
  11. Heiner

    Heiner Guest

    On Sat, 08 Oct 2005 20:10:27 +0100, Fraser Ross wrote:

    > You can't overload with a different return type alone and therefore you
    > can override with a different return type alone. I think you have an
    > unwanted way of writing a return type for assignment operators. Noone
    > has given any reason for writing them as such yet.


    Sure. The scenario is as follows: I have a class A. And I have a factory
    class AC, which creates A's and holds them. If I call a method to copy the
    contents of one AC (call it ac1) into another (call it ac2), ac2 deletes
    all its A's and creates a bunch of new one. Afterwards it calls operator=
    for every new A, passing an A from ac1. As the result, ac2 is a deep clone
    of ac1. The actual copying is done by A::eek:perator=(const A&).

    So AC looks like:

    class AC
    {
    public:
    void cloneFrom(const AC *);
    virtual A* createObject();
    };

    with the implementation

    void A::cloneFrom(const AC * source)
    {
    delete all A's stored in this
    for each a of type A in source
    {
    A * a2 = createObject();
    * a2 = * a;
    add a2 to this
    }
    }

    Okay? A simple factory pattern combined with a container plus a deep copy
    method


    Now I have a similar set of classes: B derives from A and BC from AC. BC
    is the factory of B. Now I would like to clone bc1 (of type BC) into bc2.
    What method do I need to write in BC and B?

    BC::createObject? Sure, thats how abstract factories work

    BC::cloneForm()? No! I can use the method from AC. AC::cloneFrom calls the
    virtual createObject() method, which returns a B instance now. Then it
    calls operator= on each A. As this is virtual, the right copy operator is
    called.

    Last last sentence is the key in the problem! How do I have to design A
    and B?

    Answer:

    class A
    {
    public:
    virtual A & operator= (const A &);
    };

    class B : public A
    {
    public:
    virtual A & operator= (const A &);
    virtual B & operator= (const B &);
    };


    A is clear. Please note, that there are 2 operator= in B! Why?

    B::eek:perator= (const B &): thats the natural copy operator for class B. In
    my original question I have missed it and the default copy operator
    created by the compiler caused my initial problems. The implementation of
    this operator is:

    B & B::eek:perator= (const B & src)
    {
    operator=((const A &)src);
    return * this;
    }

    it just calls the other operator=:

    B::eek:perator= (const A &) Why this? It is derived from A. It has the same
    signature as A::eek:peartor= (but different from the frist operator=, so no
    compiler error). If my AC::cloneFrom works with pointers to B instances,
    the internal *a2 = *a calls A::eek:perator= (const A &). So without my
    second operator=, B will never be copied correctly!

    I hope my problem and the solution and the need for 2 operator= in one
    class is now more clear.

    Heiner

    Remove the nospam to get my real address
     
    Heiner, Oct 8, 2005
    #11
  12. Heiner

    Rolf Magnus Guest

    Heiner wrote:

    > Sure. The scenario is as follows: I have a class A. And I have a factory
    > class AC, which creates A's and holds them. If I call a method to copy the
    > contents of one AC (call it ac1) into another (call it ac2), ac2 deletes
    > all its A's and creates a bunch of new one. Afterwards it calls operator=
    > for every new A, passing an A from ac1.


    Why doesn't it create the new As using the copy constructor?

    > As the result, ac2 is a deep clone of ac1. The actual copying is done by
    > A::eek:perator=(const A&).


    > Now I have a similar set of classes: B derives from A and BC from AC. BC
    > is the factory of B. Now I would like to clone bc1 (of type BC) into bc2.
    > What method do I need to write in BC and B?
    >
    > BC::createObject? Sure, thats how abstract factories work
    >
    > BC::cloneForm()? No! I can use the method from AC. AC::cloneFrom calls the
    > virtual createObject() method, which returns a B instance now. Then it
    > calls operator= on each A. As this is virtual, the right copy operator is
    > called.


    Ah, now I see why you need the virtual operator=. Actually, what I'd do is
    put the copying logic to the class A and not the container. I'd add a
    virtual clone() member function to A:

    virtual A* clone() const
    {
    return new A(*this);
    }

    Then in B, you override it:

    virtual B* clone() const
    {
    return new B(*this);
    }

    And then your container's cloneFrom() function would look like:

    void AC::cloneFrom(const AC * source)
    {
    delete all A's stored in this
    for each a of type A in source
    {
    A * a2 = a->clone();
    add a2 to this
    }
    }
     
    Rolf Magnus, Oct 8, 2005
    #12
  13. Heiner

    Heiner Guest

    On Sat, 08 Oct 2005 22:57:42 +0200, Rolf Magnus wrote:

    > Why doesn't it create the new As using the copy constructor?


    Because the A's created by a factory.

    > Ah, now I see why you need the virtual operator=. Actually, what I'd do is
    > put the copying logic to the class A and not the container. I'd add a
    > virtual clone() member function to A:
    >
    > virtual A* clone() const
    > {
    > return new A(*this);
    > }
    >
    > Then in B, you override it:
    >
    > virtual B* clone() const
    > {
    > return new B(*this);
    > }
    >
    > And then your container's cloneFrom() function would look like:
    >
    > void AC::cloneFrom(const AC * source)
    > {
    > delete all A's stored in this
    > for each a of type A in source
    > {
    > A * a2 = a->clone();
    > add a2 to this
    > }
    > }


    That's a good point, which I will consider. A disadvantage might be, that
    later on I might need to copy into an existing A (operator=). But I guess,
    a proper design of A, including operator=, copy constructor and clone can
    and will avoid any double coding.

    Another point is, that all of my A's know their factory. So clone actually
    requires 2 arguments (cloned object and target container). In my solution
    A is only created by the factory (private default constructor) and
    therefore knows its factory.

    On the other hand the beauty of your approach is, that it does not need a
    dynamic_cast! I will think about it.

    Thanks

    Heiner

    Remove the nospam to get my real address
     
    Heiner, Oct 8, 2005
    #13
  14. Heiner schrieb:
    > BC::cloneForm()? No! I can use the method from AC. AC::cloneFrom calls the
    > virtual createObject() method, which returns a B instance now. Then it
    > calls operator= on each A. As this is virtual, the right copy operator is
    > called.


    This won't work unless you make sure, that a BC won't store As and a AC
    won't store Bs. You can't change the type of an object during its lifetime:

    A a;
    B b;

    b = a;

    The object "b" still is of type B.

    So think about the clone() function approach and maybe an attach()
    function to move the object into another factory/container.

    Thomas
     
    Thomas J. Gritzan, Oct 9, 2005
    #14
  15. Heiner

    Heiner Guest

    On Sun, 09 Oct 2005 23:52:48 +0200, Thomas J. Gritzan wrote:

    > Heiner schrieb:
    >> BC::cloneForm()? No! I can use the method from AC. AC::cloneFrom calls the
    >> virtual createObject() method, which returns a B instance now. Then it
    >> calls operator= on each A. As this is virtual, the right copy operator is
    >> called.

    >
    > This won't work unless you make sure, that a BC won't store As and a AC
    > won't store Bs. You can't change the type of an object during its lifetime:
    >
    > A a;
    > B b;
    >
    > b = a;
    >
    > The object "b" still is of type B.


    Sure. But this problem (the mixed types within the container) does not
    occur, as the objects are created by factories only. And the AC and BC are
    the container and the factory combined. So the only way to create an A is
    to call AC::createObject. By this, the types are never mixed.

    > So think about the clone() function approach and maybe an attach()
    > function to move the object into another factory/container.


    I thought about it and I found a problem: As I work with factories and as
    I do NOT want to have mixed types, I have to pass the factory into the
    clone:

    virtual A * A::clone(AC * factory)
    {
    A * a = factory->createObject();
    do all the copying here
    }

    But how should I implement this for B?

    virtual A * B::clone(AC * factory)
    {
    A * a = factory->newObject();
    do all the copying here
    }

    But what to copy? Only the members from A? That is not sufficient, if
    factory is an instance of BC. All the members of B? This will fail, if
    factory is an instance of AC. So I have to dynamic_cast here and therefore
    the clone approach has the same advantage or disadvantage as my double
    operator= solution. I just renamed the second operator= into

    virtual void copyFrom(A *);

    so that I now have one operator= for each class and one copyFrom. Inside I
    also have to dynamic_cast to find out, what to copy.


    Heiner

    Remove the nospam to get my real address
     
    Heiner, Oct 10, 2005
    #15
  16. Heiner

    Heiner Guest

    /*
    In case someone is still reading it: A summary

    I need a factory (AC), creating objects (A). The factory also holds all
    objects it has created. AC also has a copyFrom(AC *) method: it removes
    all object created so far and replaces it with cloned objects from the
    passecd factory.

    As this is (nearly) an abstract factory pattern, there is also a B,
    derived from A with a factory BC. As there is no code dublication: BC has
    no copyFrom method. It uses AC's. In order to work, both factories have a
    virtual createObject method, which creates an A or B. Furthermore A and B
    also have a virtual copyFrom method, which copies their contents (similar
    to operator=). Now AC's copyFrom just calls createObject, to create the
    clones and on each of them copyFrom(A *), to clone the objects contents.
    This also works, if called from a BC, as everything is virtual.

    In a first aproach I named A's and B's copyFrom operator=, resulting in
    two operator= for class B. This caused some confusion. So this version
    here uses copyFrom instead of operator=.

    A disadvantage of this aproach is the need of calling dynamic_cast within
    the copyFrom, as it is possible, to call AC::copyFrom(AC*) with a BC
    instance. There was a proposal to use

    virtual A * A::clone()

    instead; but as a factory is reqiured, this must be a

    virtual A * A::clone(AC *),

    and the dynamic_cast is back. If someone has a better solution without casts....

    The attached example demonstrates it. It is bad in several aspects
    (memory leaks, no privates, ...) but it was designed to be as short as
    possible. If called, it gives:

    output:

    7of9# gmake && ./test
    g++ main.cpp -o test
    A: 69
    B::copyFrom called
    A::copyFrom called
    B: 69, 42
    B::copyFrom called
    A::copyFrom called
    B::copyFrom called with a B
    B: 69, 42
    A::copyFrom called
    A: 69

    Heiner


    */

    #include <stdio.h>

    class A { // objects to work with
    public:
    int a;
    A & operator= (const A &);
    virtual void copyFrom (const A *); // do the actual copying
    virtual void whoAmI() const {printf("A: %d\n", a);}
    };

    class AC { // factory and container. no destructor (memory leak!)
    public:
    A * oneObject; // in this example just one object
    AC() : oneObject(NULL){}
    virtual A * getObject() const {return oneObject;}
    virtual A * createObject(); // create a new object
    void copyFrom(const AC * src); // clone all objects from src!
    };

    class B : public A { // another object derived from A
    public:
    int b;
    virtual B & operator= (const B &);
    virtual void copyFrom (const A *);
    virtual void whoAmI() const {printf("B: %d, %d\n", a, b);}
    };

    class BC : public AC { // factory and container for B
    public:
    virtual A * createObject();
    B * getObjectB() const {return (B *)oneObject;} // convenience
    };


    A & A::eek:perator= (const A & src) { // call copyFrom to do the job
    copyFrom(& src);
    return * this;
    }

    void A::copyFrom (const A * src) { // copy contents
    printf("A::copyFrom called\n");
    a = src->a;
    }

    A * AC::createObject() { // create A instance
    A * result = new A;
    return oneObject = result; // store object
    }

    void AC::copyFrom(const AC * a) {
    oneObject = NULL; // delete own "container" (memory leak!)
    if (a->oneObject) { // s.th to clone?
    oneObject = createObject(); // create clone
    *oneObject = *a->oneObject; // copy data. Works for B's as well!
    }
    }

    void B::copyFrom (const A * src) { // copy B's contents
    printf("B::copyFrom called\n");
    A::copyFrom(src); // call base class
    const B * srcB = dynamic_cast<const B *>(src);
    if (srcB) { // if src is a B, copy additional stuff:
    printf("B::copyFrom called with a B\n");
    b = srcB->b;
    }
    }

    B & B::eek:perator= (const B & src) { // not used here
    copyFrom(& src);
    return * this;
    }

    A * BC::createObject() { // same as AC:: createObject
    A * result = new B;
    return oneObject = result;
    }


    int main (int)
    {
    AC ac; // 1st factory
    A * a = ac.createObject(); // create an object
    a->a = 69;
    a->whoAmI();
    BC bc; //2nd factory
    bc.copyFrom(& ac); // a is now copied into a B!
    B * b = bc.getObjectB(); // proof:
    b->b = 42;
    b->whoAmI(); // indeed: a B!
    BC bc2; // 3rd factory
    bc2.copyFrom(& bc); // b is copied into a B
    bc2.getObject()->whoAmI(); // indeed
    AC ac2; // fourth factory
    ac2.copyFrom(& bc); // now b is an A again!
    ac2.getObject()->whoAmI(); // indeed
    return 0;
    }
     
    Heiner, Oct 10, 2005
    #16
    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. Derek Simmons
    Replies:
    0
    Views:
    804
    Derek Simmons
    Aug 1, 2004
  2. Jéjé
    Replies:
    2
    Views:
    400
    Jéjé
    Nov 30, 2005
  3. while_1
    Replies:
    2
    Views:
    632
    Roedy Green
    Jun 25, 2004
  4. Jim Fischer
    Replies:
    3
    Views:
    440
    Jim Fischer
    Jul 31, 2003
  5. qazmlp
    Replies:
    7
    Views:
    494
    Howard
    Jul 27, 2004
Loading...

Share This Page