mardi 29 mars 2016

Vector of object pointers and objects going out of scope

I am using a derived class and a vector of pointers to objects from said class. I'm having some problems implementing copy constructors etc, even after reading a lot about it. I'm using c++11.

I have a loop where new objects of the derived class are created, and I then want to put these into the vector. But since it is a vector of pointers I must put the address of the created object there instead.

I believe my problems stem from this fact, together with objects going out of scope etc and my not being able to implement copy constructors / copy assignment constructors etc in a satisfactory way.

I've made a minimal example that I think illustrates my problem. Let's say the initial setup is as follows (I know it doesn't make much sense, e.g. with the pointer *n, but I think this shows the issues with my actual code):

using namespace std;
#include <iostream>
#include <vector>

class Base {

    protected:
    int* n;

    public:
    void display(string name="") {cout << name << "n = " << *n << endl;}

    Base() {}
    Base(int n_) {
        *n=n_;
        cout << "Initialised to " << *n << endl;
    }
};

class Derived : public Base {

    public:

    Derived() : Base() {}
    Derived(int n_) : Base(n_) {}
};

int main(int argc, const char* argv[]) {

    vector<Base*> list;
    for(int i=0;i<5;i++) {
        Derived tmp(i);
        tmp.display("Tmp: ");
        list.push_back(&tmp);
    }

    cout << endl;

    for(int i=0;i<list.size();i++) {
        cout << "Address of " << i << ": " << list[i] << endl;
        list[i]->display("Element "+to_string(i)+" : ");
    }

}

The output of this is:

Initialised to 0
Tmp: n = 0
Initialised to 1
Tmp: n = 1
Initialised to 2
Tmp: n = 2
Initialised to 3
Tmp: n = 3
Initialised to 4
Tmp: n = 4

Address of 0: 0x7fff3a1df2d0
Element 0 : n = 0
Address of 1: 0x7fff3a1df2d0
Element 1 : n = 0
Address of 2: 0x7fff3a1df2d0
Element 2 : n = 0
Address of 3: 0x7fff3a1df2d0
Element 3 : n = 0
Address of 4: 0x7fff3a1df2d0
Element 4 : n = 0

So after the loop all the elements in the list point to the same address, where n=0 (probably undefined behaviour from tmp going out of scope).

So rather than just putting the address of tmp into list I'm thinking I somehow have to make instances of Derived that survive the loop while still just having addresses in list.

As mentioned I've tried doing this using various special member functions with no luck.

Note that it might seem implementing a vector of the objects themselves might be easier, but that leads to other problems in my actual code. If I can't get this working I'll try that instead though.

Aucun commentaire:

Enregistrer un commentaire