How can a derived C++ class clone itself via a base pointer?

后端 未结 6 704
旧巷少年郎
旧巷少年郎 2021-01-13 09:34

Here\'s what I\'m trying to do (this code doesn\'t work):

class Base
{
    virtual Base *clone() { return new Base(this); }
    virtual void ID() { printf(\"         


        
相关标签:
6条回答
  • 2021-01-13 10:07

    You're slicing the class in Base bp = &d; (this constructs a new base bp from the derived-ptr.)

    Try Base* bp = &d; instead. (i.e. create a pointer of Base type to the Derived object.)

    0 讨论(0)
  • 2021-01-13 10:08

    The code looks fine, other than the silly syntax typos and the missing ctors.

    0 讨论(0)
  • 2021-01-13 10:15

    That code is riddled with syntactical errors. Perhaps most significantly, Derived doesn't inherit from Base. Secondly, aside from the syntactical errors (probably simple typos), Base obviously needs a virtual destructor. The clone method pretty much demands that you can call operator delete on a base pointer (Base*).

    class Base
    {
    public:
        virtual ~Base() {}
        virtual Base* clone() const { return new Base(*this); }
        virtual void ID() const { printf("BASE"); }
    };
    
    class Derived: public Base
    {
    public:
        // [Edit] Changed return type to Derived* instead of Base*.
        // Thanks to Matthieu for pointing this out. @see comments below.
        virtual Derived* clone() const { return new Derived(*this); }
        virtual void ID() const { printf("DERIVED"); }
    };
    
    int main()
    {
        Derived d;
        Base* bp = &d;
    
        Base* bp2 = bp->clone();
        bp2->ID(); // outputs DERIVED as expected
        delete bp2;
    }
    
    0 讨论(0)
  • 2021-01-13 10:17

    Your example is incorrect and will not compile. Specifically this line:

    Base bp = &d;
    

    That may also be the root cause of your problem (you may be slicing your object), but I can't tell for certain without seeing working code.

    You also have a problem where your two classes are not related (did you mean to write class Derived : public Base?)

    0 讨论(0)
  • 2021-01-13 10:26

    With Base bp = &d;

    You've "sliced" d, so to the compiler, bp really is only of type Base, which is why when you call bp->clone() the compiler calls Base::clone(); and bp2->ID() prints BASE.

    Base& bp = d; will do what you want.

    0 讨论(0)
  • 2021-01-13 10:27

    Once all the compile errors are fixed, I ended up with this:

    #include <cstdio>
    
    class Base
    {
      public:
        Base() {}
        Base(const Base&) {}
        virtual Base *clone() { return new Base(*this); }
        virtual void ID() { printf("BASE"); }
    };
    
    class Derived : public Base
    {
      public:
        Derived() {}
        Derived(const Derived&) {}
        virtual Base *clone() { return new Derived(*this); }
        virtual void ID() { printf("DERIVED"); }
    };
    
    
    int main()
    {
      Derived d;
      Base *bp = &d;
      Base *bp2 = bp->clone();
    
      bp2->ID();
    }
    

    Which gives you what you are looking for -- DERIVED.

    0 讨论(0)
提交回复
热议问题