在c ++ 11标准中,如果B类继承自A类,那么' B是A'。 但是,我仍然对这个概念感到困惑: 看看这段代码:
class Base {
public:
virtual ~Base() {}
virtual Base* clone() const = 0;
};
class Derived : public Base {
public:
virtual Base* clone() const {
return new Derived(*this);
}
//<more functions>
};
我们从Derived返回了指向Base的指针,但如果在此代码中使用此方法:
Derived* d1 = new Derived();
Derived* d2 = d1->clone();
我们所做的是在Base*
中分配Derived*
!!
问题:
为什么这段代码不能编译?为了适应继承,它怎么能被修改(为什么?)?
答案 0 :(得分:11)
您发布的代码即使经过一些简单的编辑(我制作)也无法编译。 Derived::clone()
的签名应为:
virtual Derived* clone() const override { // <-- return type
return new Derived(*this);
}
即使clone()
和Base
类中Derived
的返回类型不同,它也是virtual
函数的有效覆盖,因为co-variance是在C ++中合法。
当您处理问题中所述的指针时,不会有任何切片
Derived::clone()
应该返回Derived*
。
clone()
是否应该virtual
取决于设计,但使用virtual
析构函数时,这是一个好主意。
另一种方法是使用template
并避免virtual
:
class Base {
public:
virtual ~Base() {}
template<class T> // now need not add this trivial code in all derived classes
T* clone() const { return new T(*this); }
};