web-dev-qa-db-fra.com

std vector C ++ - copie profonde ou peu profonde

Je me demande si copier un vecteur, je copie le vecteur avec ses valeurs (alors que cela ne fonctionne pas avec le tableau, et la copie profonde a besoin d'une boucle ou d'un memcpy).

Pourriez-vous faire allusion à une explication?

Cordialement

42
kiriloff

Vous effectuez une copie complète à chaque fois que vous copiez un vecteur. Mais si votre vecteur est un vecteur de pointeurs, vous obtenez la copie des pointeurs, pas les valeurs pointées

Par exemple:

std::vector<Foo> f;
std::vector<Foo> cp = f; //deep copy. All Foo copied

std::vector<Foo*> f;
std::vector<Foo*> cp = f; //deep copy (of pointers), or shallow copy (of objects).
//All pointers to Foo are copied, but not Foo themselves
80
Andrew

Le vecteur sera redimensionné pour avoir suffisamment d'espace pour les objets. Il parcourra ensuite les objets et appellera l'opérateur de copie par défaut pour chaque objet.

De cette façon, la copie du vecteur est "profonde". La copie de chaque objet dans le vecteur correspond à ce qui est défini pour l'opérateur de copie par défaut.

Dans les exemples ... c'est le mauvais code:

#include <iostream>
#include <vector>

using namespace std;

class my_array{
public:
    int *array;
    int size;
    my_array(int size, int init_val):size(size){
        array = new int[size];
        for(int i=0; i<size; ++i)
            array[i]=init_val;
    }
    ~my_array(){
        cout<<"Destructed "<<array[0]<<endl;
        if(array != NULL)
            delete []array;
        array = NULL;
        size = 0;
    }

};

void add_to(vector<my_array> &container){
    container.Push_back(my_array(4,1));
}

int main(){

    vector<my_array> c;
    {
        my_array a(5,0);
        c.Push_back(a);
    }
    add_to(c);
    //At this point the destructor of c[0] and c[1] has been called.
    //However vector still holds their 'remains'
    cout<<c[0].size<<endl; //should be fine, as it copies over with the = operator
    cout<<c[0].array[0]<<endl;//undefined behavior, the pointer will get copied, but the data is not valid
    return 0;
}

C'est un meilleur code:

#include <iostream>
#include <vector>

using namespace std;

class my_array{
public:
    int *array;
    int size;
    my_array(int size, int init_val):size(size){
        cout<<"contsructed "<<init_val<<endl;
        array = new int[size];
        for(int i=0; i<size; ++i)
            array[i]=init_val;
    }
    my_array(const my_array &to_copy){
        cout<<"deep copied "<<to_copy.array[0]<<endl;
        array = new int[to_copy.size];
        size = to_copy.size;
        for(int i=0; i<to_copy.size; i++)
            array[i]=to_copy.array[i];
    }

    ~my_array(){
        cout<<"Destructed "<<array[0]<<endl;
        if(array != NULL)
            delete []array;
        array = NULL;
        size = 0;
    }

};

void add_to(vector<my_array> &container){
    container.Push_back(my_array(4,1));
}

int main(){

    vector<my_array> c;
    {
        my_array a(5,0);
        c.Push_back(a);
    }
    add_to(c);
    //At this point the destructor of c[0] and c[1] has been called.
    //However vector holds a deep copy'
    cout<<c[0].size<<endl; //This is FINE
    cout<<c[0].array[0]<<endl;//This is FINE
    return 0;
}
2