I have a Class that inherit from a list of pointers, example:
Class C : protected list<Type*>
Now, i want to overload the operator= (and to write the copy constructor). 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. Thus when C
is destroyed, the std::list<T>
will remain, causing a memory leak. They are not meant to be inherited form in the first place...
In a normal design, you would have the list as an 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.
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
#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:
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:
for (auto it = std::cbegin(c); it != std::cend(c); ++it) this->push_back(*it);
There's range-based for loops:
for (auto const& el : c) this->push_back(el);
There's algorithms, like 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::cbegin(c), std::cend(c), std::back_inserter(*this));
note that std::back_inserter
is an iterator that performs a push_back
while iterating.
And in the future (C++20) we will have ranges, so you can write something like
std::ranges::copy(c, *this);
Although I'm not sure that's correct...
Choose your poison!