I am trying to use assignment operator overloading to perform deep copy but not able to figure out the right way to do it. I have a Class Computer and need to use it to copy its object to that of class Laptop.
Asked
Active
Viewed 297 times
0
-
A code sample of what exactly you want to do would be appreciated. – Mihayl Dec 01 '17 at 06:20
1 Answers
1
It should look something like this:
#include <algorithm>
class SomeClass {};
class AnotherClass {};
class Computer
{
public:
Computer() :
m_someclass(new SomeClass()),
m_double(0.0)
{
}
virtual ~Computer()
{
delete m_someclass;
}
Computer(const Computer& other) :
m_someclass(new SomeClass(*other.m_someclass)),
m_double(other.m_double)
{
}
Computer& operator=(const Computer& other)
{
if (this != &other)
{
Computer tmp(other);
swap(tmp);
}
return *this;
}
void swap(Computer& other) noexcept // or throw() for before c++11
{
std::swap(m_someclass, other.m_someclass);
std::swap(m_double, other.m_double);
}
private:
SomeClass* m_someclass;
double m_double;
};
class Laptop : public Computer
{
public:
Laptop() :
m_anotherclass(new AnotherClass()),
m_int(0)
{
}
virtual ~Laptop()
{
delete m_anotherclass;
}
Laptop(const Laptop& other) :
Computer(other),
m_anotherclass(new AnotherClass(*other.m_anotherclass)),
m_int(other.m_int)
{
}
// Create a Laptop object from a Computer object
explicit Laptop(const Computer& other) :
Computer(other),
m_anotherclass(new AnotherClass()),
m_int(0)
{
}
Laptop& operator=(const Laptop& other)
{
if (this != &other)
{
Laptop tmp(other);
swap(tmp);
}
return *this;
}
// Assign a laptop object from a computer object.
Laptop& operator=(const Computer& other)
{
if (this != &other)
{
Laptop tmp(other);
swap(tmp);
}
return *this;
}
void swap(Laptop& other) noexcept // or throw() for before c++11
{
Computer::swap(other);
std::swap(m_anotherclass, other.m_anotherclass);
std::swap(m_int, other.m_int);
}
private:
AnotherClass* m_anotherclass;
int m_int;
};
int main()
{
Computer computer;
// Construct a new Laptop object by copying data from a Computer object
Laptop laptop1(computer);
// Assign Computer data in Laptop to that of a Computer object
Laptop laptop2;
laptop2 = computer;
}
For non-pointer member variables, you just perform a standard copy with operator=. For pointer member variables (that the object owns), you use the new operator and construct it with the pointer that the other object has.

Patrick Avery
- 128
- 8
-
Usually you have to release your old resources before you set new. So you need to check `if ( m_someclass && m_someclass != other.m_someclass ) delete m_someclass;` overwriting m_someclass. Also call the copy constructor only if other.m_someclass != nullptr. – Mihayl Nov 30 '17 at 20:27
-
Ah, very good points. Although, I don't think you need to check `if (m_someclass)` before deleting it because it is safe to delete a null pointer. Also, if each object "owns" its m_someclass, then I don't think two different objects will have the same m_someclass. But I put the check in there anyways. I also used `new SomeClass` on a temporary pointer for exception safety - if new throws, m_someclass will remain the same. Let me know what you think. – Patrick Avery Nov 30 '17 at 21:49
-
Right and right again, if ownership is clear. It's still not quite exception-safe. In general you need to split your code that throws apart and do it at the beginning and set the member vars in a second part that do not throw. Now you can get into situation that m_double si overwritten but m_someclass not. You can move it down or use temp var. Could also fix your class to obay the "rule of three" – Mihayl Nov 30 '17 at 22:44
-
I agree about the smart pointers. I pretty much always use them nowadays. But the OP did not give details about the types of pointers in his classes, so I just went with the traditional raw. – Patrick Avery Nov 30 '17 at 23:41
-
I moved the m_double assignment to the second part for the copy assignment. I also added a constructor and copy constructor so that it obeys the "rule of three." – Patrick Avery Dec 01 '17 at 01:55
-
I just read the question again and it talks about "*Class Computer* and need to use it to copy its *object* to that of *class Laptop*" Sounds more like copy between two different classes. Maybe you could modify your sample to match the classes mentioned in the question – Mihayl Dec 01 '17 at 06:18
-
Okay. Since I still haven't gotten more info from OP, I assumed that Computer is a base class and Laptop is a derived class. I renamed Example to Computer, and I made a nearly-identical copy of it that inherits from Computer called Laptop. One main change is that I made copy constructors and assignment operators with Computer. And then I added a small section of code in a main() function showing how you can copy and assign a Laptop object from a Computer object. Let me know if you see any problems with that code. – Patrick Avery Dec 01 '17 at 19:28
-
Got really complicated. Now you need a virtual Computer destructor. Could make Laptop's constuctor from Computer explicit. Still need to check for this != &other in the Laptop assignment with Comp. Actually almost the same code as the other assignment operator. And now we have again exception issues if the base copy passes but the following new throws. But you could use temp clone of same class and swap data if nothing throws. `Laptop tmp(other); swap(tmp, *this);` – Mihayl Dec 01 '17 at 20:33
-
Not so fast. Read https://stackoverflow.com/a/3279550/8918119. You need own swap functions and you can fix all assignments. And yo moved return int the if – Mihayl Dec 01 '17 at 20:51
-
Okay. Hopefully that looks a little better. I added some swap() functions. – Patrick Avery Dec 01 '17 at 21:54
-
Looks good. `Explicit` should be infront of the constructor name. Is simpler now. Have you tried it? – Mihayl Dec 01 '17 at 22:01
-
Done! Needed a few small change (such as a return type for swap). But I compiled it and it works! I pasted the full code above. – Patrick Avery Dec 01 '17 at 22:11