C++ 迭代&;智能指针容器

C++ 迭代&;智能指针容器,c++,inheritance,vector,iterator,shared-ptr,C++,Inheritance,Vector,Iterator,Shared Ptr,我有一个指向可变对象的智能指针容器。我必须为每个循环编写两个for_,一个用于作为只读数据访问对象,另一个用于可变数据。编译器告诉我,std::vector与std::vector不同,请注意常量 下面是我的示例代码: #include <vector> #include "boost/shared_ptr.hpp" #include <iterator> class Field_Interface { ; }; typedef boost::shared_ptr<

我有一个指向可变对象的智能指针容器。我必须为每个循环编写两个for_,一个用于作为只读数据访问对象,另一个用于可变数据。编译器告诉我,
std::vector
std::vector
不同,请注意
常量

下面是我的示例代码:

#include <vector>
#include "boost/shared_ptr.hpp"
#include <iterator>

class Field_Interface
{ ; };
typedef boost::shared_ptr<Field_Interface> Ptr_Field_Interface;
typedef boost::shared_ptr<const Field_Interface> Ptr_Const_Field_Interface;

struct Field_Iterator
  : std::input_iterator<std::forward_iterator_tag, Ptr_Field_Interface>
{
  // forward iterator methods & operators...
};

struct Const_Field_Iterator
  : std::input_iterator<std::forward_iterator_tag, Ptr_Const_Field_Interface>
{
  // forward iterator methods & operators...
};

struct Field_Functor
{
  virtual void operator()(const Ptr_Field_Interface&) = 0;
  virtual void operator()(const Ptr_Const_Field_Interface&) = 0;
};

class Record;
typedef boost::shared_ptr<Record> Ptr_Record;
typedef boost::shared_ptr<const Record> Ptr_Const_Record;

class Record_Base
{
  protected:
    virtual Field_Iterator beginning_field(void) = 0;
    virtual Field_Iterator ending_field(void) = 0;
    virtual Const_Field_Iterator const_beginning_field(void) = 0;
    virtual Const_Field_Iterator const_ending_field(void) = 0;

    void for_each(Field_Functor * p_functor)
    {
       Field_Iterator iter_begin(beginning_field());
       Field_Iterator iter_end(ending_field());
       for (; iter_begin != iter_end; ++ iter_begin)
       {
         (*p_functor)(*iter_begin);
       }
     }
};

class Record_Derived
{
public:
   typedef std::vector<Ptr_Field_Interface> Field_Container;
   typedef std::vector<Ptr_Record>          Record_Container;
private:
   Field_Container m_fields;
   Record_Container m_subrecords;
};
#包括
#包括“增压/共享_ptr.hpp”
#包括
类字段接口
{ ; };
typedef boost::共享的ptr ptr字段接口;
typedef boost::共享的ptr ptr Const字段接口;
结构域迭代器
:std::输入\迭代器
{
//正向迭代器方法和运算符。。。
};
结构常量字段迭代器
:std::输入\迭代器
{
//正向迭代器方法和运算符。。。
};
结构域函数
{
虚空运算符()(常量Ptr_字段_接口&)=0;
虚空运算符()(常量Ptr\u常量字段\u接口&)=0;
};
课堂记录;
typedef boost::共享ptr ptr_记录;
typedef boost::共享ptr ptr Const_记录;
类记录库
{
受保护的:
虚拟字段\u迭代器开始\u字段(void)=0;
虚拟字段\u迭代器结束\u字段(void)=0;
虚拟常量字段迭代器常量开始字段(void)=0;
虚拟常量字段迭代器常量结束字段(void)=0;
每个函数的void(字段函数*p函数)
{
字段迭代器iter\u begin(开始字段());
字段迭代器iter_end(end_Field());
for(;iter\u begin!=iter\u end;++iter\u begin)
{
(*p_函子)(*iter_开始);
}
}
};
类记录
{
公众:
typedef std::向量场_容器;
typedef std::向量记录容器;
私人:
字段\容器m \字段;
记录容器m_子记录;
};
鉴于以上所有细节,我如何在
Record\u-Derived
中实现
Record\u-Base
的纯抽象方法

我试过:

  • 返回
    m_fields.begin()
    ,其中
    返回转换错误(无法更改) 将std::vector转换为 字段(迭代器
  • 返回
    &m_字段[0]
    ,这是 危险,因为它假设了一些东西 关于
    std::vector
    的内部内容

  • 顺便说一句,我没有使用
    std::for_each
    ,因为我必须迭代一个包含字段的容器和一个包含子记录的容器。

    我建议在使用公共容器类型时不要编写自己的迭代器。当您编写自己的容器时,编写自己的迭代器是有意义的。但是,当您计划编写自定义迭代器时,请查看该包。

    如果您想对用户隐藏
    std::vector
    及其迭代器,则需要提供多态迭代器,以便与多态
    RecordBase
    容器一起使用。从Adobe ASL库中检出。也可能有帮助


    但是,不要考虑所有这些麻烦,你应该考虑在设计中使用复合和访问者模式。请参阅我的另一个答案。

    您所做的与和模式相似。这两种模式很好地结合在一起,所以看起来你走在了正确的轨道上

    要实现复合模式,请分配以下角色(请参阅复合模式UML图):

    • 叶->
      字段
    • 复合->
      记录
    • 组件->字段和记录的抽象基类(想不出好名字)
    对复合类型调用的组件操作将递归地传递给所有子级(叶和其他嵌套复合类型)

    要实现访问者模式,请在函子类中为每个组件子类型(字段和记录)重载
    operator()

    我建议你买一本“四人帮”的书,这本书能更好地解释这些概念,并且比我所能做的更详细

    以下是一些激发您胃口的示例代码:

    #include <iostream>
    #include <vector>
    #include "boost/shared_ptr.hpp"
    #include "boost/foreach.hpp"
    
    class Field;
    class Record;
    
    struct Visitor
    {
        virtual void operator()(Field& field) = 0;
        virtual void operator()(Record& field) = 0;
    };
    
    class Component
    {
    public:
        virtual bool isLeaf() const {return true;}
        virtual void accept(Visitor& visitor) = 0;
    };
    typedef boost::shared_ptr<Component> ComponentPtr;
    
    class Field : public Component
    {
    public:
        explicit Field(int value) : value_(value) {}
        void accept(Visitor& visitor) {visitor(*this);}
        int value() const {return value_;}
    
    private:
        int value_;
    };
    
    class Record : public Component
    {
    public:
        typedef std::vector<ComponentPtr> Children;
        Record(int id) : id_(id) {}
        int id() const {return id_;}
        Children& children() {return children_;}
        const Children& children() const {return children_;}
        bool isLeaf() const {return false;}
        void accept(Visitor& visitor)
        {
            visitor(*this);
            BOOST_FOREACH(ComponentPtr& child, children_)
            {
                child->accept(visitor);
            }
        }
    
    private:
        int id_;
        Children children_;
    };
    typedef boost::shared_ptr<Record> RecordPtr;
    
    struct OStreamVisitor : public Visitor
    {
        OStreamVisitor(std::ostream& out) : out_(out) {}
        void operator()(Field& field) {out_ << "field(" << field.value() << ") ";}
        void operator()(Record& rec) {out_ << "rec(" << rec.id() << ") ";}
        std::ostream& out_;
    };
    
    int main()
    {
        RecordPtr rec(new Record(2));
            rec->children().push_back(ComponentPtr(new Field(201)));
            rec->children().push_back(ComponentPtr(new Field(202)));
        RecordPtr root(new Record(1));
            root->children().push_back(ComponentPtr(new Field(101)));
            root->children().push_back(rec);
    
        OStreamVisitor visitor(std::cout);
        root->accept(visitor);
    }
    
    #包括
    #包括
    #包括“增压/共享_ptr.hpp”
    #包括“boost/foreach.hpp”
    类字段;
    课堂记录;
    结构访问者
    {
    虚空运算符()(字段和字段)=0;
    虚拟void运算符()(记录和字段)=0;
    };
    类组件
    {
    公众:
    虚拟布尔isLeaf()常量{return true;}
    虚拟作废接受(访客和访客)=0;
    };
    typedef boost::shared_ptr ComponentPtr;
    类字段:公共组件
    {
    公众:
    显式字段(int值):值(value){}
    无效接受(访客和访客){Visitor(*this);}
    int value()常量{返回值}
    私人:
    int值;
    };
    类记录:公共组件
    {
    公众:
    typedef-std::矢量子对象;
    记录(int-id):id_u(id){
    int id()常量{return id_;}
    Children&Children(){return Children}
    const Children&Children()const{return Children}
    bool isLeaf()常量{return false;}
    无效接受(访客和访客)
    {
    访客(*本页);
    BOOST_FOREACH(组件PTR和儿童、儿童)
    {
    儿童->接受(访客);
    }
    }
    私人:
    int-id_2;;
    儿童;
    };
    typedef boost::共享_ptr RecordPtr;
    struct OStreamVisitor:公共访问者
    {
    OStreamVisitor(std::ostream&out):out{(out)}
    
    void运算符()(字段和字段){out\uu我很好奇,你到底想用什么编译器来编译这个示例?VC8和GCC3/4不起作用。@gf:我想他可能在使用STLPort,它仍然有
    std::forward\u迭代器
    模板,以便与标准的早期草案向后兼容。@gf,@Emile:My bad,标识符应该是
    std::forward\u迭代器标签
    。我正在使用MS Visual Studio 2008。最相似的示例不会编译,因为它是一个显示概念的精简版本。@Emile:谢谢,我对Visitor很熟悉,我将使用复合模式刷新我的记忆。我突然想到一个主意:将
    录制库
    简化为容器,然后转换为标准co