C++ 如何在c++;?

C++ 如何在c++;?,c++,inheritance,iterator,C++,Inheritance,Iterator,我想用这种方式实现迭代器。但编译器显示错误 class List{ public: class ListIterator{ public: }; typedef ListIterator iterator; virtual iterator begin() = 0; }; class ArrayList:public List{ public: class ArrayLi

我想用这种方式实现迭代器。但编译器显示错误

class List{

    public:
        class ListIterator{

            public:

        };
        typedef ListIterator iterator;
        virtual iterator begin() = 0;
};
class ArrayList:public List{
    public:
        class ArrayListIterator{

            public:

        };
        typedef ArrayListIterator iterator;
        iterator begin(){

        }
};
class LinkedList:public List{

    public:
        class LinkedListIterator{

            public:

        };
        typedef LinkedListIterator iterator;
        iterator begin(){

        }
};
LinkedList也是如此

当我在堆栈溢出上搜索相同的问题时,我得到了这个解决方案

我有两个解决方案

[Error] invalid covariant return type for 'virtual ArrayList::iterator ArrayList::begin()'
[Error] overriding 'virtual List::iterator List::begin()'

但我想知道,有没有任何可能的方法使迭代器成为ArrayList、LinkedList和List的内部类???

您需要ArrayListIterator从ListIterator派生

派生类中begin返回的类型不是从基列表类中begin返回的类型派生的


这就是为什么错误说它们不是协变的。

您需要抛弃基于继承的多态性。标准库中的C++迭代和<>代码>(:)/Cord>Road假定基于值的迭代器,基于继承的多态性与基于值的迭代器不起作用。 您应该使用基于类型擦除的多态性,而不是基于继承的多态性。这需要一点样板,因为抽象处理一个迭代范围的需求在C++中并不常见,而且经常是严重的性能命中。 但我会告诉你怎么做

基于类型擦除的多态性类似于
std::function

消除类型多态性的一种具体方法:

您可以确定要支持的接口。称之为“类型擦除目标”。您的类型擦除目标不是一个具有
virtual
=0
的类,而是一组您想要支持的函数、方法和操作,以及它们的签名,以及对每个函数、方法和操作的描述

然后编写一个值类来实现该接口(同样,没有继承),该接口包含一个
pImpl
(请参见
pImpl
模式),它将其操作分派给该接口(pImpl不需要匹配相同的接口,它只需要可以实现操作的原语。在这里最小化是值得的)

pImpl
类型确实有
virtual
方法和
=0
抽象方法

然后编写一个构造函数或工厂函数,该函数接受一个支持所需接口的对象,并生成
pImpl
的具体实例,然后将值类包装在其周围

假设类型擦除目标是“打印到流”


<我的类型擦除目标是 STD::OFSULD,你的设计是什么意思?这看起来像是一个用C/J/java语言设计的,它讨厌值类型和接口C++编写C++的接口。我想用列表接口设计一个ARARYList类和LIKEDList类。所以,你的设计的重点是你的设计。进行设计的原因。进行设计的原因是设计的用途。标准库容器不使用基于继承的多态性。忽略这一事实会有您自己的危险。不,如果您愿意,您可以使用多态性来进行设计,但您需要知道,如果您想将类与STLD一起使用,stl的工作方式不是这样的将ListIterator派生到ArrayListIterator会产生相同的错误。正如lorro指出的,您还需要开始通过指针(或引用)返回因此,它将以多态方式工作。-1为什么?原始帖子中消息中的错误是由解释的原因造成的。需要很长时间才能确定整个想法是否合理。我不是-1,但您的答案并不能解决OP的问题。OP做出您建议的更改后,代码仍然无法编译。折叠指针建议进入,您正在取得进展,但这不在您的答案中。这意味着您正在告诉OP手动管理指针拥有的资源,这本身可能值-1!是的,在实现std collections接口的上下文中,我的答案失败,因为begin不会以标准的指针/引用返回在d集合中,我打算编辑以建议使用非虚拟接口模式返回一个对象来包装特定于容器的迭代实现,但你在这一点上击败了我。因为概念迭代和多态性并不是不兼容的。stl确实不是这样工作的,但要断言需要抛弃多态性的想法是正确的正确。能够针对一个集合进行编码通常很有用,您知道该集合将迭代某一类型,而不必知道该集合类型是否为向量/列表/数组。如果这些迭代器用于stl算法(OP没有说明哪一个)这是不同的。@ Rx C++标准迭代器是值类型。值类型不是(基于继承的)多态性。如果OP使用“迭代器”这个术语来表示不同于“迭代器”的意思。在C++中,我会感到惊讶,并建议OP改变术语的使用。我描述了如何做多态值类型,以匹配必须执行的C++标准“迭代”概念。这包括<代码>(:)/Cuth-Road支持,超出 STD< /Calp>算法。我把迭代器看作是一个模式——“关于”。SOs迭代器上的标签很好地涵盖了这一点。您是否有具体的建议,说明在谈论迭代器模式时,如何“更改术语的使用”,但不一定要具体说明遵循stl设计的模式?
1 . implement iterator without using runtime polymorphism
2 . implement seperator iterator class.
struct printable_view {
  // dispatch to pimpl:
  friend std::ostream& operator<<( std::ostream& o, printable_view const& p ) {
    p->print(o);
    return o;
  }
  // pimpl:
private:
  struct printable_view_impl {
    virtual ~printable_view_impl() {}
    virtual void print(std::ostream& o) = 0;
  };
  std::unique_ptr<printable_view_impl> pImpl;

private:
  template<class T>
  struct printer:printable_view_impl {
    printer( T const* p ):ptr(p) {}
    T const* ptr; // just a view, no ownership
    virtual void print( std::ostream& o ) final override {
      o << *ptr;
    }
  };
public:
  // create a pimpl:
  printable_view(printable_view&&)=default;
  printable_view(printable_view const&)=delete;
  printable_view()=delete;
  template<class T>
  printable_view( T const& t ):
    pImpl( std::make_unique<printer<T>>( std::addressof(t) ) )
  {}
};
template<class T>
struct any_iterator_sorta {
  T operator*()const { return pImpl->get(); }
  void operator++() { pImpl->next(); }
  any_iterator_sorta(any_iterator_sorta const& o):
    any_iterator_sorta( o.pImpl?any_iterator_sorta(o.pImpl->clone()):any_iterator_sorta() )
  {}
  friend bool operator==(any_iterator_sorta const& lhs, any_iterator_sorta const& rhs ) {
    if (!lhs.pImpl || ! rhs.pImpl)
      return lhs.pImpl == rhs.pImpl;
    return lhs.pImpl->equals( *rhs.pImpl );
  }
  friend bool operator!=(any_iterator_sorta const& lhs, any_iterator_sorta const& rhs ) {
    return !(lhs==rhs);
  }
  any_iterator_sorta(any_iterator_sorta&& o) = default;
  any_iterator_sorta() = default;

  any_iterator_sorta& operator=(any_iterator_sorta const& o) {
    any_iterator_sorta tmp=o;
    std::swap(tmp.pImpl, o.pImpl);
    return *this;
  }
  any_iterator_sorta& operator=(any_iterator_sorta&& o) = default;
private:
  struct pimpl {
    virtual ~pimpl() {}
    virtual void next() = 0;
    virtual T get() const = 0;
    virtual std::unique_ptr< pimpl > clone() const = 0;
    virtual bool equals( pimpl const& rhs ) const = 0;
  };
  std::unique_ptr< pimpl > pImpl;
  template<class It>
  struct pimpl_impl:pimpl {
    It it;
    virtual void next() final override { ++it; }
    virtual T get() const final override { return *it; }
    virtual std::unique_ptr< pimpl > clone() const final override {
      return std::make_unique<pimpl_impl>( it );
    }
    virtual bool equals( pimpl const& rhs ) const final override {
      if (auto* r = dynamic_cast<pimpl_impl const*>(&rhs))
        return it == r->it;
      return false;
    }
    pimpl_impl( It in ):it(std::move(in)) {}
  };
  any_iterator_sorta( std::unique_ptr< pimpl > pin ):pImpl(std::move(pin)) {}
public:
  template<class It,
    std::enable_if_t< !std::is_same<It, any_iterator_sorta>{}, int>* =nullptr
  >
  any_iterator_sorta( It it ):
    pImpl( std::make_unique<pimpl_impl<It>>( std::move(it) ) )
  {}       
};
void test( any_iterator_sorta<int> begin, any_iterator_sorta<int> end )
{
  for (auto it = begin; it != end; ++it) {
    std::cout << *it << '\n';
  }
}

std::vector<int> v{1,2,3};
std::list<int> l{10,11};

test( begin(v), end(v) );
test( begin(l), end(l) );
    virtual any_iterator_sorta<int> begin() = 0;
    virtual any_iterator_sorta<int> end() = 0;
   any_iterator_sorta<int> begin() final override {
     return ArrayListIterator{};
   }
   any_iterator_sorta<int> end() final override {
     return ArrayListIterator{};
   }
   class ArrayListIterator{

   public:
     int operator*() const { return 0; }
     bool operator==( ArrayListIterator const& o ){return true;}
     void operator++() { /* do nothing for now */ }
   };