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

不羁岁月 提交于 2019-12-19 07:54:04

问题


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("BASE");
};

class Derived : publc Base
{
    virtual Base *clone() { return new Derived(this); }
    virtual void ID() { printf("DERIVED"); }
}

.
.
Derived d;
Base *bp = &d;
Base *bp2 = bp->clone();

bp2->ID();

What I'd like is to see "DERIVED" printed out... what I get is "BASE". I'm a long-time C programmer, and fairly experienced with C++... but I'm not making any headway with this one... any help would be appreciated.


回答1:


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.




回答2:


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;
}



回答3:


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.




回答4:


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.)




回答5:


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?)




回答6:


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



来源:https://stackoverflow.com/questions/3136646/how-can-a-derived-c-class-clone-itself-via-a-base-pointer

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!