C ++两个不同向量中的相同对象

时间:2015-07-02 08:36:59

标签: c++ object vector duplicates

我正在开发一个C ++项目,我想知道是否可以将同一个对象存储在两个不同的向量中。我知道如何用C指针处理它,所以你将同一个对象引用到两个表中,但我在C ++中有点困惑。

如果我创建一个对象并将其存储在向量a和向量b中。 C ++是否复制了对象,或者它在两个向量上都是相同的,如果我修改了一个,另一个也被修改了吗?在第二种情况下,是否需要更多地方存储它两次(对于可访问性问题)或者它不是一个好处理它的方法?

感谢。

4 个答案:

答案 0 :(得分:3)

Cppreference是查看此类问题的好地方。让我引用链接的相关部分:

  

void push_back(const T& value);

     

void push_back(T&& value);

     

将给定的元素值追加到容器的末尾。

     

1)新元素初始化为值的副本。

     

2)将值移入新元素。

所以是的,在两个向量中存储两次相同的元素会导致它被复制两次。如果您不想浪费内存,则应使用std::vector<T*>。和往常一样,你也应该考虑智能指针(std::shared_ptr / std::weak_ptr)而不是裸指针。

答案 1 :(得分:2)

它真的与C类似。

如果您拥有的是vector<object>,那么您将使用不同的对象。

另一方面,vector<object*>确保您只存储指向对象的指针,然后让多个向量包含相同的对象或对象不是问题。

在使用C ++中的指针时,您还可以考虑使用std::shared_ptrstd::weak_ptr来简化内存管理。

答案 2 :(得分:1)

当您将对象插入std::vector时,会将其复制一份:

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

如果您不想要副本,可以使用指针或std::reference_wrapper(您不能使用引用,因为它们不能满足容器值类型的限制):

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

当然,现在不需要确保a的生命周期不短于向量的生命周期,否则您将快速转向未定义的行为。

你也可以使用std::shared_ptr来确保你的对象在没有更多引用时被破坏:

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

答案 3 :(得分:0)

我为你做了一个简单的例子:

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;
}

输出:

2 3 5 5