[英]Copy Constructor or overloading Operator= with an inherited list of pointers
I have a Class that inherit from a list of pointers, example:我有一个从指针列表继承的 Class,例如:
Class C : protected list<Type*>
Now, i want to overload the operator= (and to write the copy constructor).现在,我想重载 operator= (并编写复制构造函数)。 Should i iterate the list making a new Type for each pointer inside the list?
我应该迭代列表,为列表中的每个指针创建一个新类型吗?
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);
}
}
}
or can i do this?或者我可以这样做吗?
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);
}
}
}
I've edited my answer, as this is a homework exercise我已经编辑了我的答案,因为这是一个家庭作业
In a normal application you shouldn't derive from a STL container, their destructors are not virtual.在普通应用程序中,您不应从 STL 容器派生,它们的析构函数不是虚拟的。 Thus when
C
is destroyed, the std::list<T>
will remain, causing a memory leak.因此,当
C
被销毁时, std::list<T>
将保留,从而导致 memory 泄漏。 They are not meant to be inherited form in the first place...它们一开始并不意味着继承形式......
In a normal design, you would have the list as an object:在正常设计中,您会将列表作为 object:
#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;
}
};
What I would consider a GOOD exercise is that you implement a MyList
class, making everything from scratch.我认为一个好的练习是你实现了一个
MyList
class,一切从头开始。 But it is common knowledge that professors make student do weird illogical stuff.但众所周知,教授让学生做奇怪的不合逻辑的事情。 So lets assume you indeed want to derive from
std::list
and only overload operator=
, doing the copy yourself因此,假设您确实想从
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;
}
};
Now, how do you copy... many flavors: There's the good-old C-style loop:现在,你如何复制......多种口味:有古老的 C 风格循环:
for (int i = 0; i < c.size(); ++i) this->push_back(c[i]);
There's the iterator loop:有迭代器循环:
for (std::list<T*>::const_iterator it = c.cbegin(); it != c.cend(); ++it) this->push_back(*it);
There's the iterator loop with auto
and generalized accessors:有带有
auto
和通用访问器的迭代器循环:
for (auto it = std::cbegin(c); it != std::cend(c); ++it) this->push_back(*it);
There's range-based for loops:有基于范围的 for 循环:
for (auto const& el : c) this->push_back(el);
There's algorithms, like std::for_each
有算法,比如
std::for_each
std::for_each(std::cbegin(c), std::cend(c), [this](T* ptr) { this->push_back(ptr); });
... and std::copy
...和
std::copy
std::copy(std::cbegin(c), std::cend(c), std::back_inserter(*this));
note that std::back_inserter
is an iterator that performs a push_back
while iterating.请注意,
std::back_inserter
是一个迭代器,它在迭代时执行push_back
。
And in the future (C++20) we will have ranges, so you can write something like并且在未来(C++20)我们将有范围,所以你可以写类似的东西
std::ranges::copy(c, *this);
Although I'm not sure that's correct...虽然我不确定这是否正确...
Choose your poison!选择你的毒药!
It depends what you want to do!这取决于你想做什么!
The first performs a deep copy ;第一个执行深拷贝; the second just performs a shallow copy of the pointers in the list, and thus does nothing that the original
std::list
implementation didn't do.第二个只是执行列表中指针的浅拷贝,因此没有做原始
std::list
实现没有做的事情。
Also, if(!(*this)==c))
is wrong;另外,
if(!(*this)==c))
是错误的; it has too many )
and was probably intended to be if (this != &c)
.它有太多
)
并且可能打算是if (this != &c)
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.