【发布时间】:2019-10-12 22:20:33
【问题描述】:
这个问题是关于拥有指针、使用指针、智能指针、向量和分配器。
我对代码架构的想法有点迷茫。此外,如果这个问题在某个地方已经有了答案,1. 抱歉,我目前还没有找到满意的答案;2. 请指点我。
我的问题如下:
我有几个“东西”存储在一个向量中,以及这些“东西”的几个“消费者”。所以,我的第一次尝试如下:
std::vector<thing> i_am_the_owner_of_things;
thing* get_thing_for_consumer() {
// some thing-selection logic
return &i_am_the_owner_of_things[5]; // 5 is just an example
}
...
// somewhere else in the code:
class consumer {
consumer() {
m_thing = get_thing_for_consumer();
}
thing* m_thing;
};
在我的应用程序中,这将是安全的,因为在任何情况下,“事物”都比“消费者”更长寿。但是,在运行时可以添加更多“东西”,这可能会成为一个问题,因为如果 std::vector<thing> i_am_the_owner_of_things; 被重新分配,所有 thing* m_thing 指针都会变得无效。
解决这种情况的方法是直接存储指向“事物”而不是“事物”的唯一指针,即如下所示:
std::vector<std::unique_ptr<thing>> i_am_the_owner_of_things;
thing* get_thing_for_consumer() {
// some thing-selection logic
return i_am_the_owner_of_things[5].get(); // 5 is just an example
}
...
// somewhere else in the code:
class consumer {
consumer() {
m_thing = get_thing_for_consumer();
}
thing* m_thing;
};
这里的缺点是“事物”之间的记忆连贯性丢失了。可以通过某种方式使用自定义分配器来重新建立这种内存一致性吗?我正在考虑像分配器这样的东西,它总是会为例如 10 个元素分配内存,并且在需要时添加更多的 10 元素大小的内存块。
示例:
最初:
v = ☐☐☐☐☐☐☐☐☐☐
更多元素:
v = ☐☐☐☐☐☐☐☐☐☐ ???? ☐☐☐☐☐☐☐☐☐☐
又一次:
v = ☐☐☐☐☐☐☐☐☐☐ ???? ☐☐☐☐☐☐☐☐☐☐ ???? ☐☐☐☐☐☐☐☐☐☐
使用这样的分配器,我什至不必使用“事物”的std::unique_ptrs,因为在std::vector 的重新分配时间,已经存在的元素的内存地址不会改变。
作为替代方案,我只能考虑通过 std::shared_ptr<thing> m_thing 引用“消费者”中的“事物”,而不是当前的 thing* m_thing,但这对我来说似乎是最糟糕的方法,因为“事物”应该不拥有“消费者”并且使用共享指针我将创建共享所有权。
那么,分配器方法是一种好方法吗?如果是这样,怎么办?我必须自己实现分配器还是现有的分配器?
【问题讨论】:
-
多个消费者使用相同的东西吗?因为如果不是,将所有权从载体转移到消费者不是更合适吗?
-
你知道
things的最大数量吗?如果是,则在向量上调用reserve,并且不会重新分配元素。 -
是的,多个消费者可以使用同一个东西。这就是重点,所有权不得转移给消费者。
-
@MarekR 是的,这可能是一个选择。但它永远不会是一个干净的解决方案,因为一方面,您希望这个上限尽可能紧。如果您在极少数情况下需要更多,该怎么办?
-
“这里的缺点是“事物”之间的内存一致性丢失了。” - 为什么它很重要?
标签: c++ c++11 shared-ptr unique-ptr allocator