Copy Constructor for complex classes

I am familiar with the simple copy constructors, and it worked fine with classes which members are primitives as strings or integers.

However now I am trying to make a copy constructor for a bit more complex class.
Here is an example code,
there is a class "Modules, a struct "Hardware" and a class "Computer" in which Modules and Hardware are stored.
The member "Computer_Hardware", of the class "Computer", stores a vector of "Hardware" structs.
So how can you make a copy constructor for the class "Computer" ?
I wrote my first thought, but ofc it is not working.
Thanks in advance !


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
  class Modules{

public:
	Modules() {}
	Modules(double P, std::string NM) :
		price(P),
		Name_Module(NM)
	{};
	~Modules();

private:
	std::string Name_Module;
	double price;
};
Modules::Modules(){}
Modules::~Modules(){}


struct Hardware{

	double TotalPrice;
	std::vector<Modules> Hardware_Modules;
};


class Computer
{
public:
	Computer(){}
	Computer(std::vector<Hardware> HW, double BuildY, std::string I_D) :
		Computer_Hardware(HW),
		BuildYear(BuildY),
		ID(I_D)
	{};
	~Computer();

	//Problem Copy Constructor
	Computer(const Computer& copy) {
		Computer_Hardware = new std::vector<Hardware>(copy.Computer_Hardware);
		BuildYear = new double(copy.BuildYear);
		ID = new std::string(copy.ID);
	}

private:
	std::vector<Hardware> Computer_Hardware;
	double BuildYear;
	std::string ID;
};

Computer::Computer(){}
Computer::~Computer(){}
Line 39-41: You're using the new operator which returns a pointer. Simply use the assignment operator.
1
2
3
4
5
Computer(const Computer& copy) 
{   Computer_Hardware = copy.Computer_Hardware;
    BuildYear = copy.BuildYear;
    ID = copy.ID;
}


Well it is not fulfilling the function of a copy constructor, since I want to allocate a new instance of the class with the same values, but at a new address.
I tried it however without the new operator, thanks anyways.
I want to allocate a new instance of the class with the same values, but at a new address.

You do that by doing:
 
  Computer * newinstance = new Computer (oldinstance);

That will allocate a new instance of Computer at a new address and invoke the copy constructor to copy over the values to the new instance.
It isnt taking the values from the oldinstance,
is there anything to change in the copy constructor maybe?

1
2
3
4
Computer(const Computer& copy) {
		std::vector<Hardware>* Computer_Hardware = new std::vector<Hardware>(copy.Computer_Hardware);
		
	}

Last edited on
Doesn't look like you need to do anything. Just remove the copy constructor and you're done. The implicitly defined copy constructor will do what you want.
> with the same values, but at a new address.
1
2
3
4
5
6
int main(){
   Computer a;
   Computer b(a);
   std::cout << &a.Computer_Hardware << '\n';
   std::cout << &b.Computer_Hardware << '\n';
}
I already showed you how to implement your own copy constructor. vector, string and double all support copy semantics. You don't need to create new dynamic instances. Simply copy the individual elements as I showed you above.

The following line create a local pointer to a vector that goes out of scope when the constructor exits creating a memory leak.
 
std::vector<Hardware>* Computer_Hardware = new std::vector<Hardware>(copy.Computer_Hardware);
Last edited on
Yea thanks for your help, however I still havent solved my problem. It is probably because I have pointers in my classes, so the plain copy doesnt work very well.
If e.g. the struct Hardware and the class Module have pointers, I need to make a deep copy constructor, right?
Do I need to make then only a Computer deep copy constructor or for the struct Hardware and Module aswell?
the copy constructor provided by the compiler will call the copy constructor of the members of your class.
if that behaviour suits you, then let it be.

> If e.g. the struct Hardware and the class Module have pointers,
I'll suggest you to use the smart pointer that gives you the behaviour that you want.
clepina wrote:
It is probably because I have pointers in my classes

That's not the code you showed us.
Topic archived. No new replies allowed.