存储在矢量中的对象的所有权
Ownership of objects stored in a vector
我正在学习C++,但我遇到了一个小问题。我有一些Foo类的实例。我有一个vector<Foo> data
的FooContainer,方法是
void FooContainer::add(Foo item) {
this->data.push_back(item)
}
我希望FooContainer成为Foo元素的真正持有者。我不明白什么是将项目从main传递到Foo的更好方法。
我主要有:
Foo item(...);
container.add(item);
通过这种方式,我在main中分配了一个对象,并将一个副本传递给容器。我有一个元素存在于2个位置,所以我必须在所有add()
之后删除主元素中的一个。
还是最好在main中有一个指针,用new
关键字构造项,然后传递指针?这样Container.data应该是vector<Foo*>
吗?
或者,再次将元素放在main中,通过引用添加到容器中,而不在main中删除它?
我有点困惑。
编辑
出于教育目的,我不想使用c++11或boost共享指针:我的想法在指针、引用和基本事物上都很困惑,在进入高级争论之前(即使更优雅),我想对我正在做的事情有一个清晰的基础!
这一切都取决于您的需要。
如果您的所有实例都是Foo
[而不是Foo
]的子类,则使用vector<Foo>
的IMO更简单,因此应该是首选。
但是,如果您有一个扩展了Foo
的类Bar
,那么尝试将其添加到vector
中将导致对象切片,并且您的程序将无法正常运行。在这种情况下,您应该更喜欢vector<Foo*>
因此,正如我开始的那样,这一切都取决于具体的需求,但如果您计划扩展Foo
,则必须考虑最后一点。
我发现boost::ptr_vector对于显式所有权语义非常有效。
我这样使用它(注意,我使用VC9,因此我使用std::auto_ptr
而不是改进的std::unique_ptr
):
//use unique_ptr instead if they are supported on your compiler
std::auto_ptr<MyClass> a( new MyClass("a") );
boost::ptr_vector<MyClass> owning_vector;
owning_vector.push_back(a);
// auto_ptr a is now invalid and the ownership of the object is
// solely with owning_vector
因此,它将解决您创建2个对象的问题,并且还将清楚谁拥有新对象。此外,在语义方面,boost的API指针容器家族具有比原始指针向量(IMO)更自然的sytax。
您可以将临时文件传递到容器中;这将在线路的最后被销毁:
container.add(Foo(...));
在C++11中,您可以直接将其构建到容器中:
template <typename Args...>
void FooContainer::emplace(Args && a) {
data.emplace_back(std::forward(a));
}
container.emplace(...);
(我的语法可能不太正确,因为我很少使用可变模板)
在这两种情况下,请记住容器存储类型为Foo
的对象。不能存储子类型的对象;如果您尝试,对象将通过只复制基类部分而被"切片"。如果你需要存储子类型(正如你的一条评论所暗示的那样),那么你就必须存储指针。
还是最好在main中有一个指针,用new关键字构造项,然后传递指针?
这会造成在从容器中删除对象时记住删除对象的复杂性。您可以在C++11中使用vector<unique_ptr<Foo>>
,或者在C++03中使用boost::ptr_vector<Foo>
来处理这一问题。这样做的好处是,如果你想这样做的话,你也可以在容器中存储Foo
子类型的对象
或者,再次将元素放在main中,通过引用添加到容器中,而不在main中删除它?
不能将引用放入容器中。您可以将指向局部变量的指针放在容器中,只要非常小心,它们在使用中不会被破坏(如果所有内容都在main
中确定范围,这就足够简单了)。同样,这允许您存储Foo
的子类型,而不仅仅是Foo
本身。
我认为这不是所有权的问题,而是开销的问题。
如果您有vector<foo>
,则每次将对象添加到向量时,它都会将值复制到向量
因此,除了创建要添加到向量中然后删除的临时对象外,您还在向量中创建另一个对象,复制那里的值。
因此,最好只创建一个vector<foo*>
来保存对象。
或者最好使用shared_ptr<foo>
和vector<shared_ptr<foo>>
- 对象超出范围/转让所有权
- 从函数返回范围视图时,带有std::span:中间对象所有权的C++Ranges-v3
- Qt对象所有权内存泄漏
- 如何将对象的所有权传递给函数的外部
- 唯一 ptr 将所有权移动到包含对象的方法
- 如何为生存时间少于对象所有者的类组织对象所有权?
- UI自动化回调中com对象的所有权
- 使用PYBIND11,如何为Array_t对象设置基础内存的所有权
- C (MVC模式)中的对象所有权
- 可以提升::p ython将对象的所有权传递给python回调函数
- std::unique_ptr 来转移 const 对象的所有权
- 如何在不复制和保留 std::string 对象的情况下获得 C++ std::string 字符数据的所有权
- 我能不能做一个unique_ptr不拥有其尖头对象的所有权
- 指向没有所有权的堆栈对象的指针
- 在C++11中,将对象的所有权从一个unique_ptr转移到另一个unique _ptr
- 存储在矢量中的对象的所有权
- 如何在C++或Winapi中转移同步对象的所有权
- NSArray如何获得一个c++对象的所有权
- 使用“放置新”转移对象所有权
- 在 std::分配器重新绑定上转移对象所有权