# C++ : Deep Copying of an Object

• C/++/#
Gold Member
I'm making a basic neural network, and I haven't programmed in an object oriented way since java in undergraduate. Everything lately has been c and fortran 77.

I have an object that is a "Network"
In addition to functions and locals, it includes a pointer to an array of another object "Layer"
Each Layer includes a pointer to an array of "Neuron"
Each Neuron includes a pointer to an array of "Connection"
Connection just has a double "val".

How do I create an operator and copy constructor such that when I have

Code:
Network A;
A.Randomize(); //Sets everything to random values at the Connection level
Network B = A; //Here I want to define a copy
B.Randomize(); //Randomize B

And then
A.Layers[0].Neurons[0].Connections[0].val
B.Layers[0].Neurons[0].Connections[0].val

should be different. As it stands, the basic shallow copy makes copies of the pointer locations, rather than the deep values contained. So A.Layer and B.Layer point to the same location, so any changes to B makes changes to A. I want to make a NEW duplicate, that does a deep copy.

Do I need to go to each class and add a more deep copy constructor with rules for EVERY pointer/array/object in that class, and how to copy itself deeply?

It feels like a lot of work, where if inside say Neuron class I have a bunch of different pointers, I would have to make the copy constructor copy the value of each one?

Sorry if its not clear, I have an idea of what I'm doing but I'm having trouble getting it done. It also doesn't help that im working off of someone elses template to a very basic degree.

jtbell
Mentor
Do I need to go to each class and add a more deep copy constructor with rules for EVERY pointer/array/object in that class, and how to copy itself deeply?

Pretty much so, yes. In fact, each class should have a destructor, a (deep) copy constructor, and an assignment operator (the "Rule of Three").

This would be easier if the classes used vectors instead of arrays. You can copy a vector of objects (e.g in an assignment statement), and it automatically copies all the objects it contains, according to their constructors. With arrays, you have to copy each object yourself.

D H
D H
Staff Emeritus
This would be easier if the classes used vectors instead of arrays.
What jtbell said!

I have an object that is a "Network"
In addition to functions and locals, it includes a pointer to an array of another object "Layer"
Each Layer includes a pointer to an array of "Neuron"
Each Neuron includes a pointer to an array of "Connection"
Connection just has a double "val".
If you follow jtbell's advice, you don't need to write a copy constructor, assignment operator, or destructor. The C++ standard library contains some very powerful capabilities, they optimize very nicely, and they oftentimes eliminate the need to write those rule of three (C++11: rule of five) special member functions.

Code:
class Connection {
public:
// Default constructor
Connection(double v=0.0) : val(v) {}

// Other member functions
...

double val;
};

There is need to declare a copy constructor, assignment operator, destructor for class Connection. In fact, you don't want to. The implicitly-defined functions do exactly what the doctor ordered. If you're of the pedantic sort, you can inform the reader of your code that you are explicitly using those implicitly declared and defined member functions:

Code:
class Connection {
public:
// Default constructor
Connection(double v=0.0) : val(v) {}

// Copy constructor, assignment operator, and destructor
Connection(const Connection&) = default;
Connection& operator=(const Connection&) = default;
~Connection() = default;

// And in the case of C++11/14 ...
Connection(Connection&&) = default;
Connection& operator=(Connection&&) = default;
// Other member functions
...

double val;
};

I kind of like that myself. It's not too that extra typing, and it tells me as a reader of the code that the author of the class has explicitly thought about whether it makes sense to get those freebies.

What about higher levels? Here's neuron, which now uses a vector rather than a primitive array:

Code:
class Neuron {
public:
// Default constructor, needed if you define a non-default constructor
// and if you want a default constructor. I'm assuming C++11 here.
Neuron() = default;

// Defaulted special member functions.
// Once again I'm being pedantic here. Now this is perhaps too much typing.
Neuron(const Neuron&) = default;
Neuron(Neuron&&) = default;
Neuron& operator=(const Neuron&) = default;
Neuron& operator=(Neuron&&) = default;
~Neuron() = default;
...
std::vector<Connection> connections;
};

And similarly for classes Layer and Network.

The rule of three is a pain in the rear. The rule of five, and even bigger pain. The easiest way around this is to use Peter Sommerlad's "rule of zero": Write your classes so you don't need to define any of the special member functions that are subject to the rule of three / rule of five. Use standard library containers or smart points.

Gold Member
DH, I'm going to implement it that way, but basically it becomes that YOUR copy is a shallow copy, but since im using vectors rather than pointers to arrays, its easy and I can just use the normal shallow copy for everything. Right?

It doesn't solve the problem of if I had a pointer for some reason deep in my tree that the copy used would just copy the address rather than the value?

D H
Staff Emeritus
DH, I'm going to implement it that way, but basically it becomes that YOUR copy is a shallow copy, but since im using vectors rather than pointers to arrays, its easy and I can just use the normal shallow copy for everything. Right?
It's a deep copy rather than a shallow copy if you replace all those primitive arrays with std::vectors.

Make a Neuron contain a vector of Connection objects, a Layer contain a vector of Neuron objects, a Network contain a vector of Layer objects. The implicitly defined copy constructor for Network invokes the std::vector copy constructor to make a copy of the source Network object's connections vector. The std::vector copy constructor makes an element-by-element copy. That means the Lay objects will be copied element by element, which in turn means the Neuron elements within each Layer will be copied element by element, which in turn means the Connection objects within each Neuron will copied element by element. That's a deep copy, just what you want, and you get it for free by following the rule of zero.

Gold Member
Ok, thanks a million! Time to rewrite all of this...

chiro