使用继承的指针列表复制构造函数或重载运算符=

Copy Constructor or overloading Operator= with an inherited list of pointers

本文关键字:构造函数 重载 运算符 复制 列表 继承 指针      更新时间:2023-10-16

我有一个从指针列表继承的类,例如:

Class C : protected list<Type*>

现在,我想重载运算符=(并编写复制构造函数(。我应该迭代列表,为列表中的每个指针创建一个新的类型吗?

void C::operator=(const C& c)
{
if(!(*this)==c))
{
clear();
for(list<Type*>::iterator it = c.begin(); it != c.end(); it++)
{
Type* cp = new Type((*it)); //or doing cp=&(*it) after the new
push_back(cp);
}
}
}

或者我可以这样做吗?

void C::operator=(const C& c)
{
if(!(*this)==c))
{
clear();
for(list<Type*>::iterator it = c.begin(); it != c.end(); it++)
{
Type* cp = it; //or cp=&(*it)
push_back(cp);
}
}
}

我已经编辑了我的答案,因为这是一个家庭作业练习

在一个普通的应用程序中,你不应该从STL容器派生,它们的析构函数不是虚拟的。因此,当C被破坏时,std::list<T>将保留,从而导致内存泄漏。它们一开始就不应该被继承。。。

在正常的设计中,您会将列表作为一个对象:

#include <list>
template<typename T>
class C {
private:
std::list<T*> lst;
public:
C& operator=(const C& c) {
if (this != &c) {
lst = c.lst;
}
return *this;
}
};

我认为GOOD练习是实现一个MyList类,从头开始制作所有东西。但众所周知,教授会让学生做一些奇怪的、不合逻辑的事情。因此,假设您确实想从std::list派生,并且只重载operator=,自己复制

#include <list>
template<typename T> 
class C : protected std::list<T*>
{
public:
constexpr C& operator=(C const& c) noexcept {
if (this != &c) {
this->clear();
// copy
}
return *this;
}
};

现在,你如何复制。。。多种口味!有一个很好的C风格循环:

for (int i = 0; i < c.size(); ++i) this->push_back(c[i]);

有一个迭代器循环:

for (std::list<T*>::const_iterator it = c.cbegin(); it != c.cend(); ++it) this->push_back(*it);

有一个带有auto和广义访问器的迭代器循环:

for (auto it = std::cbegin(c); it != std::cend(c); ++it) this->push_back(*it);

有基于范围的循环:

for (auto const& el : c) this->push_back(el);

有一些算法,比如std::for_each

std::for_each(std::cbegin(c), std::cend(c), [this](T* ptr) { this->push_back(ptr); });

std::copy

std::copy(std::cbegin(c), std::cend(c), std::back_inserter(*this));

注意,std::back_inserter是在迭代时执行push_back的迭代器。

在未来(C++20(,我们将有范围,所以你可以写一些类似的东西

std::ranges::copy(c, *this);

虽然我不确定这是正确的。。。

选择你的毒药!

这取决于你想做什么!

第一个执行深度复制;第二个只是执行列表中指针的浅拷贝,因此没有做原始std::list实现没有做的任何事情

此外,if(!(*this)==c))是错误的;它有太多的CCD_ 13,并且可能是有意成为CCD_。