-2

i am having difficulty understanding how this concept of creating new objects on the fly in a vector container seem to work, as seen in link at time 18:30. It seems the author constructs a vector of classes like so

class a;
typedef vector<a> b;
.
.
.
vector<b> c;
.
. 
.
for (unsigned x=0;x<num_of_b_obj.size();x++){
c.push_back(b); //seems to be a way to dynamically create an array 
                //of objects of b in vector container c
}

does anyone know how this works, and is there any good documentation of this concept ?

The typical way of constructing an object is to instantiate the class, followed by the object name, like class_name object_name1 and class_name object_name2, then to use the object members freely like object_name1.function_a. The issue with using the vector container to construct the object seems to be, then how would one use, member functions of different object, if there are no visible ways of assigning a name to the constructed object ?

below is the real code ... showing the "push_back()" method seemingly creating new objects in a loop

class Neuron(){};

typedef vector<Neuron> Layer;

class Net {

public:
    Net(vector<unsigned> &topology) // class constructor
    void feedForward(const vector<double> &inputVals) {}; // passing 
inputVals by reference rather than by value, because inputVals will be too 
HUGE to pass by copying the value.
    void backProp(const vector<double> &targetVals) {};
    void getResults(vector<double> &resultVals) const {};
private:
    vector<Layer> m_layers; // m_layer[layerNum][neuronNum]
};


Net::Net(vector<unsigned> &topology)
{
    unsigned numLayers = topology.size();
    for (unsigned layerNum=0;layerNum < numLayers;++layerNum){
        m_layers.push_back(Layer()); // create new empty layer, to fill with the i'th neuron

        for(unsigned neuronNum=0; neuronNum <= topology[layerNum];++neuronNum){
            m_layers.back().push_back(Neuron()); // ".back()" to access the newly created layer, ".push_back()" to append the new neuron in the new layer 
            cout<< "Made a neuron foo !!" << endl;
        }


    }

}
  • The vector stores information it needs to know both how many elements are in the vector, and what the maximum number of elements it can hold before it needs to grow. `push_back` uses this logic to first grow the vector's storage if necessary, and then add the element. If it doesn't need to grow, it just adds the element. – paddy Nov 19 '18 at 03:59
  • Regarding documentation: [std::vector](https://en.cppreference.com/w/cpp/container/vector) – paddy Nov 19 '18 at 04:01
  • The author actually explains in the video what each part of the code is doing (and your code doesn't match what's in the video). – melpomene Nov 19 '18 at 04:01
  • Same video, but better quality: https://vimeo.com/19569529 – melpomene Nov 19 '18 at 04:03
  • 1
    You can use `[ ]` to access the elements of a vector. – melpomene Nov 19 '18 at 04:07
  • `push_back` is not what's constructing the new object. As the video explains, `push_back` is used to add a new element to the vector. – melpomene Nov 19 '18 at 04:16
  • 1
    `c.push_back(b);` should generate a compilation error. Please post real code – M.M Nov 19 '18 at 04:28
  • 1
    @melpomene `push_back` does construct a new object in the vector (copy/move-constructed from the argument) – M.M Nov 19 '18 at 04:29
  • @melpomene if push_back() is not constructing the object, then how is the object being constructed ? – TheSprintingEngineer Nov 19 '18 at 05:44

2 Answers2

1
m_layers.push_back(Layer());

is equivalent to

m_layers.push_back(vector<Neuron>());

This calls the constructor for a vector. The important thing that's missed between your example code and the actual code is

c.push_back(b);   // compiler error since `b` is a type

should be

c.push_back(b());

The parentheses can make a difference.

vector<Neuron>() // this constructs an empty vector of neurons.
vector<Neuron>   // this is a type.

the "push_back()" method seemingly creating new objects in a loop

I think you're misunderstanding how constructors work.

The object is created just before it is pushed into the vector. So it's not really the push_back() that's doing the creating.

m_layers.push_back(vector<Neuron>());
//                 ^^^^^^^^^^^^^^^^    // a new object is created

// ...

m_layers.push_back(aNewObject);        // the new object is passed into `push_back`

// ...   

What really happens behind the scenes, with push_back() is that the object will copied into the vector. So surprise surprise,

m_layers.push_back(vector<Neuron>());

actually creates two objects, but one of them is quickly destroyed while the other one is stored into the vector.

The typical way of constructing an object is to instantiate the class, followed by the object name, like class_name object_name1

That's one way of doing it, and it's not wrong.

vector<Neuron> someNeuron;
m_layers.push_back(someNeuron);

That works. It'll compile finely. But since we won't be using the variable someNeuron elsewhere, we can just do it "on the fly", without needing an instance_name or an object_name.

m_layers.push_back(vector<Neuron>());

This may be a good time to get a C++ book to read or look up a tutorial on classes, review what you know, and explore different types of constructors/class implementations. There are plenty out of guides/tutorials out there.

TrebledJ
  • 8,713
  • 7
  • 26
  • 48
  • ahh thanks !!! I guess the root of my confusion is in constructing new objects using default constructors via parenthesis, and you cleared this right up – TheSprintingEngineer Nov 19 '18 at 08:58
0
vector<b> c;
c.push_back(b);

I will give a explanation:

(1) the containter (names 'c;) may be enlarge its internal buffer if need, to have enough space for new element.

(2) the containter invoke element's copy constructor at the new element's address (located somewhere in the internal buffer). that means:

call new(element's address) b;

so you paramter is copy-constructed to the internal buffer of the container, and your passed-in parameter owned by you can be destroyed or freeed. The container hold a copy of the object, and maintains all the elements's lifetime.

Exlife
  • 99
  • 6