【问题标题】:Encapsulating an object offered from an iterator封装从迭代器提供的对象
【发布时间】:2016-10-26 13:21:58
【问题描述】:

我有一个名为Base 的类,它在内部保存一个SomeType 类型的对象容器。 然后我创建class Derived: protected Base

现在我想在Derived 类中创建自定义迭代器,以使用户能够迭代Base 类中容器中的对象。问题是SomeType 提供了更多我想提供的功能,即我想隐藏SomeType 中提供的一些功能,并可能添加一些额外的数据字段和功能。


所以我尝试做的一件事是像这样包装SomeType

class AnotherType{
    private:
        SomeType& object;
    public:
    //Make visible what I want
}

然后在迭代器中的operator*() 内部创建一个新的AnotherType 对象并返回它。

我的问题是,我不能这样做:

Derived d;
for(auto& object: d)
    // Use object however i like.

注意 auto 中的“&”。

如果我不添加任何额外的数据字段,另一种可能的解决方案是使用this 之类的东西。但正如我所见,这是未定义的行为。

有什么想法吗?

【问题讨论】:

  • 所以你的问题是你想抑制这个对象,但是你不能在无人居住的情况下使用它?
  • 你能提供一些 mcvs 的例子吗?
  • @StoryTeller 我想隐藏SomeType 的界面的一部分,但我想出的主要解决方案,要做到这一点,会产生那个特殊的问题。
  • 您是否有任何特殊原因要使用for(auto& object: d) 而不仅仅是for(auto object: d)
  • @user183833 如果您的AnotherType 只是SomeType 的包装以限制功能并且它已经包含对SomeType 对象的引用,您将能够改变底层@987654340 @ 对象而不通过引用获取 AnotherType。至于复制,取决于。同样,如果所有AnotherType 都是对SomeType 的引用,那么复制就是一件简单的事情。

标签: c++


【解决方案1】:

由于您希望迭代器返回引用,因此您需要有一个可以返回引用的非临时对象。最简单的方法是让您的迭代器类包含AnotherType 的实例,并让AnotherType 的成员成为Base 的迭代器而不是引用,以便在@987654325 时可以更新它@迭代器被修改。

class AnotherType{
    private:
        Base::iterator iter;
    public:
        AnotherType(Base::iterator it) : iter(it) { }
    //Make visible what I want
        void Foo() { iter->Foo(); }
};

【讨论】:

  • 我犹豫不决的原因是因为:例如,如果用户 while 在一个范围内迭代 for 循环并可能保留一个指向先前取消引用的迭代器值的指针,它将在下一次重复,就像现在在那个内存中存储的最新值一样。这基本上遵循input iterator semantics。不过,感谢您的意见,最后,如果没有更好的选择,那就是这个或我的第一个初始选择。
猜你喜欢
  • 1970-01-01
  • 2011-10-03
  • 2011-11-22
  • 1970-01-01
  • 1970-01-01
  • 2011-03-24
  • 2013-05-18
  • 2010-09-23
相关资源
最近更新 更多