C++ 迭代&;智能指针容器
我有一个指向可变对象的智能指针容器。我必须为每个循环编写两个for_,一个用于作为只读数据访问对象,另一个用于可变数据。编译器告诉我,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<
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