所以我想在派生类中覆盖纯抽象方法,但是我得到了这个错误。有人可以帮助我看看发生了什么,我怎样才能完成它。
我的Device
课程;
class Device {
public:
Device();
Device(const Device& orig);
virtual ~Device();
virtual Device Clone() = 0;
}
我的派生类;
class Radar : public Device {
public:
Radar();
// Radar(const Radar& orig); // commenting so the compiler using its default copy constructor
virtual ~Radar();
Radar Clone();
};
我的Radar
类的源文件;
Radar Radar::Clone() {
return *(new Radar(*this));
}
如果我在Device
类的Clone
方法中使用Device
类型,则会弹出Device
是抽象类。
如果我使用void
类型(我假设它不是我想要的),则会显示我没有实现此方法。
我该怎么办?
答案 0 :(得分:3)
您的Clone
方法需要返回指向克隆对象的指针...协变返回类型只能以这种方式工作(因为返回值要求调用者将返回的值复制到堆栈中 - 这将是当您使用new
)分配内存泄漏时。
所以,它应该是:
virtual Device* Clone() = 0;
......以后......
Radar* Clone(); // YES, it should be Radar* here - that uses C++'s support for
// "covariant return types", see also "UPDATE" discussion
Radar* Radar::Clone()
{
return new Radar(*this);
}
更新 - 按要求进一步解释
因此,使用克隆函数的想法是它可以返回您Device*
当前正在寻址的任何实际派生类型的深层副本。鉴于派生类型可能会添加Device
缺少的数据成员,它可能是一个更大的对象,并且调用者无法保留适当的堆栈空间来存储它。因此,需要使用new
动态分配对象,并且可预测大小的Device*
是调用者访问新对象的方式。克隆函数返回Radar*
是合法的 - 这意味着客户端代码在编译时知道它正在处理Radar
并且克隆它可以继续使用它作为Radar
- 访问Radar
提供的任何额外成员。
希望有助于澄清事情。您可能还想对面向对象的编程进行一些背景阅读。
答案 1 :(得分:1)
实施此cloning technique的经典方法是将covariant return types用于Clone()
方法。结合现代RAII技术(例如unique_ptr
等),它提供了一种非常灵活和安全的组合,可以适当地管理和克隆对象。
协变返回类型的一个优点是,您可以获取克隆对象(深层副本),并且返回类型与层次结构中相同的级别作为参数 (即返回并不总是基类)并且不需要立即转换。在C ++中,指针和引用支持协方差,值不支持协方差。
建议对原始画家使用智能指针(如unique_ptr
)以避免内存泄漏。 clone_unique
工厂是根据标准库中相应的make_unique
工具建模的,并返回unique_ptr
。它包含对参数和目标类型的类层次结构的显式类型检查。
该解决方案确实需要使用std::unique_ptr
。如果您的编译器不可用,boost会为这些提供替代方案。还有一些其他较新的C ++语言功能,但如果需要,可以删除它们。
#include <type_traits>
#include <utility>
#include <memory>
class Device {
public:
virtual Device* Clone() const = 0;
};
class Radar : public Device {
public:
virtual Radar* Clone() const override {
// ^^^^^^ covariant return compared to Device::Clone
return new Radar(*this);
}
};
// Clone factory
template <typename Class, typename T>
std::unique_ptr<Class> clone_unique(T&& source)
{
static_assert(std::is_base_of<Class, typename std::decay<decltype(*source)>::type>::value,
"can only clone for pointers to the target type (or base thereof)");
return std::unique_ptr<Class>(source->Clone());
}
int main()
{
std::unique_ptr<Radar> radar(new Radar());
std::unique_ptr<Device> cloned = clone_unique<Device>(radar);
}
See this related answer更长的例子。
答案 2 :(得分:-1)
请尝试以下签名
虚拟设备&amp;克隆()= 0; 要么 虚拟设备*克隆()= 0;
//体
Device& Radar::Clone() {
return Radar(*this));
}