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

C++ same object in two different vectors

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

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

谢谢。

Cppreference 是检查这类问题的好地方。让我引用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.

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

它真的很像 C。

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

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

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

当您将一个对象插入 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 的生命周期不短于 vector 的生命周期,否则你将快速走向未定义的行为。

您也可以使用 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

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

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