我正在做一种名为"深度复制"的事情,clone()方法需要使用其复制构造函数返回派生类类型的新实例
设备.h
class Device : public Object{
public:
Device();
Device(const Device& copy);
~Device();
virtual Device* clone() = 0;
};
Radar.h
class Radar : public Device {
public:
Radar();
~Radar();
Radar(const Radar &Copy);
Device* clone();
};
Radar.cpp
Radar::Radar() {
}
Radar::Radar(const Radar& copy) {
}
Radar::~Radar() {
}
Device* Radar::clone() {
}
我不知道如何使用复制构造函数来处理这个方法,有人能帮我吗?
注意:您可能需要考虑在派生类中使用Radar* clone() override;
,这将允许派生类型的实例克隆自己并维护相同的类型(这被称为协变返回类型)。
使用其复制构造函数返回派生类类型的新实例
return new Radar(*this);
new
,因为您需要指向类的新实例的指针*this
,因为复制构造函数签名是Radar(const Radar&)
具有虚拟函数的类通常没有复制构造函数,因为复制此类的对象通常没有意义。允许复制构造函数打开了与切片相关的各种危险错误的大门。
换句话说(我强调):
我正在做一种名为"深度复制"的事情,clone()方法需要使用派生类类型的副本返回其新实例构造函数
不,它绝对不需要复制构造函数。它应该通过删除复制构造函数和复制赋值运算符来防止复制。
下面是一个应该如何做到这一点的例子。请注意,我已经将析构函数设置为虚拟的,并添加了一些示例成员。我还将clone
的签名更改为const
,并使用override
来启用额外的编译检查。
class Device : public Object {
public:
Device() {}
Device(const Device&) = delete;
Device& operator=(const Device&) = delete;
virtual ~Device() {}
virtual Device* clone() const = 0;
};
class Radar : public Device {
public:
Radar(int i, const std::string& s) : i(i), s(s) {}
Radar* clone() const override
{
return new Radar(i, s);
}
private:
int i;
std::string s;
};
根据您的设计需要,clone
调用的Radar
构造函数也可以是private
。
另一件事是,你可能想考虑一个基于std::unique_ptr
的设计:
class Device : public Object {
public:
Device() {}
Device(const Device&) = delete;
Device& operator=(const Device&) = delete;
virtual ~Device() {}
virtual std::unique_ptr<Device> clone() const = 0;
};
class Radar : public Device {
public:
Radar(int i, const std::string& s) : i(i), s(s) {}
std::unique_ptr<Device> clone() const override
{
return std::make_unique<Radar>(i, s);
}
private:
int i;
std::string s;
};