问题
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