我应该使用哪种 c++11 范例来最小化内存使用量并最小化复制?
What c++11 paradigm should I use to minimize memory-usage and minimize copying?
PROBLEM
我有一个抽象接口Series
和一个具体的类Primary_Series
,它通过存储大量值来满足接口std::vector<>
。
我还有另一个具体的类Derived_Series
它本质上是Primary_Series
的变换(例如,一些大的Primary_Series
乘以 3),我希望节省空间,所以我不想将整个派生系列存储为成员。
template<typename T>
struct Series
{
virtual std::vector<T> const& ref() const = 0;
};
template<typename T>
class Primary_Series : Series<T>
{
std::vector<T> m_data;
public:
virtual std::vector<T> const& ref() const override { return m_data; }
}
template<typename T>
class Derived_Series : Series<T>
{
// how to implement ref() ?
}
问题
我应该如何更改此接口/纯虚拟方法?
我不想按值返回该向量,因为它会给Primary_Series
引入不必要的复制,但在Derived_Series
的情况下,我肯定需要创建某种临时向量。 但是,我面临着一个问题,即一旦调用者完成它,我如何使该向量消失。
如果ref()
返回对临时的引用,随着引用的消失而消失,那就太好了。
这是否意味着我应该使用某种std::weak_ptr<>
? 这是否符合Primary_Series
的工作方式?
满足"最小化内存使用量"和"最小化复制"要求(包括在调用方完成后使Derived_Series
暂时消失)的最佳方法是什么?
好吧,界面设计本身带来了一些问题,因为C++并没有真正懒惰。
现在,由于Derived_Series
应该是原始Primary_Series
的延迟计算(因为您希望节省空间)变换,因此您不能返回完整胖向量的引用。(因为这需要您先构造它。
因此,我们必须更改_Series
共享数据的界面和方式。使用std::shared_ptr<std::vector<>>
在Primary_Series
和Derived_Series
之间共享数据,以便超出范围Primary_Series
不会使转换的数据无效。
然后,您可以将界面更改为更"矢量"。也就是说,实现部分(或全部)常用的数据访问函数(operator[]
、at()
...)和/或自定义迭代器,从原始序列返回转换后的值。这些将允许你隐藏一些实现细节(转换的懒惰,数据的共享......),并且仍然能够以最大的效率返回转换后的值,并让人们将你的类用作"类似向量",所以你不必改变太多的设计。(~任何使用向量的算法在意识到你的类后都可以使用它。
我还勾勒出了一个非常基本的例子来说明我的意思。
(注意:如果你有一个多线程设计和可变Primary_Series
,你将不得不考虑你需要同步的位置和内容。
---edit---
在仔细考虑之后,我还必须指出,无论如何,Derived_Series
的实现都会有点痛苦。它的方法必须按值返回,它的迭代器基本上是伪装成更高类迭代器的输入迭代器,因为通过引用返回延迟计算的值并不真正起作用,或者它必须填写它自己的数据结构,因为原始序列的位置被评估,这将带来完全不同的权衡。
一种解决方案是使用std::shared_ptr<vector<T> >
将向量存储在基类中,并使用它来返回向量的值。基类只返回其成员值,派生类创建一个新向量并通过shared_ptr返回该向量。然后,当调用方不再需要派生类的返回值时,它将自动销毁。
或者,您可以将类设计为模仿std::vector<T>
的接口,但设计基类,使其返回转换后的值而不是常规值。这样,就永远没有必要返回。如果您不想为std::vector<T>
具有的所有函数编写方法,则可以制作某种可以迭代和转换std::vector<T>
的转换迭代器。那么你甚至不必有一个复杂的类层次结构。
一种方法是定义你自己的iterator
,并使你的vector<T>
私有。基本上,您将拥有纯虚拟访问器begin()
和end()
.Derived_Series
将包装Primary_Series
的迭代器并动态转换值。
- 找到两对数字,使它们的乘积的绝对差最小化
- 我可以做些什么来消除或最小化这种将提供相同功能和行为的代码重复
- 超轻 - 如何最小化窗口
- 在C++中使用 GSL 最小化
- 在C++中最小化变量的范围
- 当只有一个线程主要使用该对象而其他线程很少使用它时,如何最小化该对象的互斥锁锁定?
- "最小化"按钮不会出现在 MFC 对话框中
- 从小于或等于某个 N 的数字列表中最小化或找到 n 个理想的子集和
- 如何排列二进制字符串以最小化它们之间的距离
- 最小化 C++ 中的内存使用
- 禁用 GPO 的空气抖动最小化
- 如何隐藏最大化和最小化按钮并在qml应用程序窗口中显示关闭按钮?
- 如何使用 stl 最小化 c++ 中所有打开的窗口
- 如何最小化嵌入式平台上的内存分配
- 可见程序或最小化程序时的过程ID更改
- 删除/最小化GIT合并冲突
- 当模式窗口最小化时,最小化所有应用程序窗口(在 Linux 上)
- 我应该使用哪种 c++11 范例来最小化内存使用量并最小化复制?
- 如何使用写入时复制来最小化 C++ 程序的内存消耗
- 最小化总结构内存