简体   繁体   中英

C++ same object in two different vectors

I'm working on a C++ project and I wonder if it's possible to store the same object in two different vector. I know how to deal with it in C with pointer, so you reference the same object to both table, but I'm little bit confused in C++.

If I create an object and I store it in vector a and in vector b. Do C++ copy the object or it's the same on both vector and if I modify one, the other is modified too ? In the second case, does it take more place to store it twice (for accessibility issues) or it's not a good way to deal with it ?

Thanks.

Cppreference is a great place to check exactly this type of questions. Let me quote the relevant parts of the link:

void push_back( const T& value );

void push_back( T&& value );

Appends the given element value to the end of the container.

1) The new element is initialized as a copy of value.

2) value is moved into the new element.

So yes, storing the same element twice in two vectors will cause it to get copied twice. You should use std::vector<T*> if you don't want to waste memory. And as always, you should also consider smart pointers ( std::shared_ptr / std::weak_ptr ) instead of naked pointers.

It's similar to C, really.

If what you have is a vector<object> , then you'll be working with different objects.

On the other hand, a vector<object*> ensures that you'll only be storing pointers to your objects and then having multiple vectors containg the same object or objects is not an issue.

You might also consider using std::shared_ptr and std::weak_ptr to simplify memory management when working with pointers in C++.

When you insert an object into a std::vector a copy of it is made:

Foo a;
std::vector<Foo> vec1;
std::vector<Foo> vec2;
vec1.push_back(a); //copy made
vec2.push_back(b); //copy made

If you do not want a copy, you can either use pointers or std::reference_wrapper (you can't use references as they don't fulfil constraints on container value types):

Foo a;
std::vector<Foo*> vec1;
std::vector<std::reference_wrapper<Foo>> vec2;
vec1.push_back(&a); //no copy
vec2.push_back(std::ref(b)); //no copy

Of course, now no need to ensure that the lifetime of a is no shorter than that of the vectors, otherwise you're on the fast-track to undefined behaviour.

You could also use std::shared_ptr which will ensure that your object is destructed when there are no more references to it:

std::shared_ptr<Foo> a = std::make_shared<Foo>();
std::vector<std::shared_ptr<Foo>> vec1;
std::vector<std::shared_ptr<Foo>> vec2;
vec1.push_back(a); //reference count incremented
vec2.push_back(a); //reference count incremented

I made a simple example for you:

class SomeObject { public: int a; };

int main()
{
    SomeObject some_object;
    some_object.a = 1;

    //Copies are made
    std::vector<SomeObject> foo;
    foo.push_back(some_object);

    std::vector<SomeObject> bar;
    bar.push_back(some_object);

    foo.at(0).a = 2;
    bar.at(0).a = 3;

    std::cout << foo.at(0).a << ' ' << bar.at(0).a;

    //Refers to the same object
    std::vector<SomeObject*> baz;
    baz.push_back(&some_object);

    std::vector<SomeObject*> foobar;
    foobar.push_back(&some_object);

    baz.at(0)->a = 4;
    foobar.at(0)->a = 5;

    std::cout << ' ' << baz.at(0)->a << ' ' << foobar.at(0)->a;

    return 0;
}

Outputs:

2 3 5 5

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM