两个不同向量中的 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_ptr
和 std::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
我正在处理一个 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_ptr
和 std::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