【发布时间】:2013-09-16 21:48:13
【问题描述】:
一些(相关的?)背景:
我有一个类在 c++ 中提供类似迭代器的功能。它用于解压缩大型数据集。在幕后,我有一个CompressedData 对象。迭代器类对压缩数据进行迭代,返回未压缩的Data对象
Data ExpandingIterator::operator*() const;
取消引用操作符返回一个 Data 而不是 Data& 因为没有任何地方可以存储未压缩的 Data 对象来持久化。例如,压缩数据可能包含以下三个条目:
- 5'3',
- 3 个 1,
- 6 个“0”
然后当你用 ExpandingIterator 迭代这个集合时,你会得到:
3, 3, 3, 3, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0
3 和 1 和 0 永远不会同时存在于数组的某个位置。它们是从压缩数据中一次一个地扩展的。现在,真实数据比简单的整数更复杂。有数据、时间戳和其他方法可以将数据转换为其他形式的数据。
问题: 我已经成功实现了上面提到的解引用操作符。问题是当我使用 ExpandingIterator 并想要访问 Data 对象上的方法之一时,我最终会写
(*iterator).Method()
我更喜欢写
iterator->Method();
到目前为止,这个问题的解决方案似乎很明显。我需要实现 -> 运算符。这最初看起来很简单,但我担心我遗漏了一些东西(可能很明显)
一开始,我试过了:
Data ExpandingIterator::operator->() const{
return **this; //Just call the regular dereference operator
}
但这给我留下了错误消息:类型'Data'没有重载成员'operator ->'。更多研究,基于this answer here,我相信有一些可能的解决方案:
- 也给“数据”一个 -> 运算符。不幸的是,我认为这只会将我对问题的误解推到 Data 对象中,在那里我会遇到与我在这里遇到的完全相同的问题
- 返回指向“数据”对象的指针。不幸的是,Data 对象并不真正存在于可以指向的位置,所以这似乎是一个非首发
- 给 Data 一个隐式对象以进行指针转换 - 这对我来说似乎很荒谬。
- 放弃,回家吧。只需执行 (*Data).Method() 并被 c++ 击败。
有人可以帮助消除对 -> 运算符应该如何实现的误解(或缺乏理解)吗?
【问题讨论】:
-
operator ->应该返回一个指向您希望应用->的实例的指针,或者一个实现->重载的(引用)对象。 -
难道不能在迭代器类中存储一个 Data 实例并返回一个指向该实例的指针吗?无论如何,这似乎是一个好主意,因为如果迭代器被多次访问,该实例基本上将用作缓存。如果您的减压步骤很昂贵,那可能很重要。
-
@dsharlet 这不是一个糟糕的主意。解压步骤并不昂贵,它只依赖于跟踪您已经迭代了多少解压项目。话虽如此,将当前数据项保留在某个地方并没有什么坏处
-
@jxh 棘手的部分是我不确定要返回指针的实例应该驻留在哪里。
标签: c++ iterator operator-overloading