提问人:botetta 提问时间:4/13/2022 更新时间:4/13/2022 访问量:153
深度复制派生类中的指针向量
Deep copying a vector of pointers in derived class
问:
我有一个名为 Cipher 的纯虚拟类
class Cipher
{
public:
//This class doesn't have any data elements
virtual Cipher* clone() const = 0;
virtual ~Cipher() { };
//The class has other functions as well, but they are not relevant to the question
};
Cipher 还有其他一些派生类(例如 CaesarCipher)。问题将是关于 CipherQueue 的,它看起来像这样:
//I've tried to only include the relevant parts here as well
class CipherQueue: public Cipher
{
std::vector<Cipher*> tarolo;
public:
void add(Cipher* cipher)
{tarolo.push_back(cipher);}
CipherQueue(const CipherQueue& _rhs); //?????
CipherQueue* clone() const; //?????
~CipherQueue()
{
for (size_t i = 0; i < tarolo.size(); i++)
{
delete tarolo[i];
}
//tarolo.clear(); //not sure if this is needed
}
CipherQueue 有一个名为 tarolo 的向量。它包含指向 Cipher 的派生类的指针。您可以使用 new 运算符或给定类的 clone 函数(已实现)向此向量添加元素:
CipherQueue example;
example.add(new CaesarCipher(3))
CaesarCipher c(6);
example.add(c.clone());
//It is the job of the CipherQueue class to free up the memory afterwards in both cases
现在的问题是:如何在 CipherQueue 中实现复制构造函数和克隆函数,以便在克隆函数中使用复制构造函数,并且克隆函数创建调用它的对象的深度副本?
我已经做了我认为是浅拷贝的东西,这并不好,因为析构函数不能与浅拷贝一起使用。 (或者析构函数也可能是错的吗?
目标是使它能够使您可以执行以下操作:~CipherQueue()
CipherQueue example;
CipherQueue inside; //Let's say that this already has a few elements in it
example.add(inside.clone());
example.add(example.clone()); //This should also work
这是我之前尝试过的,没有使用复制构造函数(我认为这是一个浅层副本,因此它会导致我的程序出现分段错误):
CipherQueue* clone() const
{
CipherQueue* to_clone = new CipherQueue;
to_clone->tarolo = this->tarolo;
return to_clone;
}
答:
0赞
botetta
4/13/2022
#1
谢谢 Marius Bancila,你是对的,问题是我只是复制指针,而不是在新向量中创建新对象。我在每个对象上调用了 clone(),现在它运行良好!这是工作克隆功能,以防将来有人偶然发现此线程:
CipherQueue* clone() const
{
CipherQueue* to_clone = new CipherQueue;
to_clone->tarolo = this->tarolo; //First we copy the pointers
for (size_t i = 0; i < this->tarolo.size(); i++)
{
to_clone->tarolo[i] = tarolo[i]->clone(); //Then we use the clone function on each element to actually create new objects, and not just have copied pointers
}
return to_clone;
}
最后,似乎我根本不需要复制构造函数。您可以在没有它的情况下使克隆功能。
评论
to_clone->tarolo = this->tarolo;
导致两个对象指向相同的对象,最终导致双重删除。使用任何你使用的地方,删除自定义析构函数,编译器将防止你犯这些类型的错误。CipherQueue
Cipher
std::unique_ptr<Cipher>
Cipher*
tarolo
Cipher