请释疑解惑

匚匚 2011-03-10 04:39:05
定义了如下一个类模板,如果它的数据成员是一个含多个数据成员的类对象时,如果逐个去修改这个成员中的数据成员(非全部更改)?
#ifndef CLIST_H_
#define CLIST_H_
template <typename T>
class clist
{
public:
clist(); ~clist(); class Iterator;
Iterator begin() const;
Iterator end() const;
void push_back(const T&);
void pop_head();
size_t size()const;
void edit(const Iterator&,T&);
template <typename U>
void edit(const Iterator&,U,int,void (*)(const Iterator&,U,int));//这个接口对吗,应如何实现?
template <typename U>
friend std::ostream& operator<<(std::ostream& out,const clist<U>& lst);
private:
struct lnode
{
lnode* next; T val;
};
lnode* front; lnode* rear; size_t _size;
};
//...
#endif //CLIST_H_

#ifndef STU_H_
#define STU_H_
struct node
{
node(){}
node(std::string name,std::string sex,int id,float ave)
{ _name=name;_sex=sex;_id=id;_ave=ave; }
std::string _name; std::string _sex; int _id; float _ave;

friend std::istream& operator>>(std::istream&,node&);
friend std::ostream& operator<<(std::ostream&,const node&);
};
std::istream& operator>>(std::istream& in,node& n)
{
std::cout<<"依次输入姓名/性别/学号/成绩:";
in>>n._name>>n._sex>>n._id>>n._ave;
return in;
}
std::ostream& operator<<(std::ostream& out,const node& n)
{
out<<"姓名:"<<n._name<<std::endl<<"性别:"<<n._sex<<std::endl
<<"学号:"<<n._id<<std::endl<<"成绩:"<<n._ave<<std::endl;
return out;
}
#endif //STU_H_
...全文
179 16 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
匚匚 2011-03-11
  • 打赏
  • 举报
回复
http://blog.csdn.net/longhuihu/archive/2011/02/19/6195235.aspx
中有一句:
traits扮演特性提取机的角色,这里所谓迭代器特性,指的就是迭代器的相应类型。若要这个traits能够有效运作,每一个迭代器必须遵守约定,以嵌套类型定义的方式,声明所需的相关类型,谁不遵守这个约定就不能容于stl这个大家庭。

在clist<T>的公有部分中进行了类型提取,在iterator中不是也能使用吗?
另,类中的语句有没有先后顺序?
pengzhixi 2011-03-11
  • 打赏
  • 举报
回复
额,没这样的约定吧。类型的定义应该在clist<T>和iterator中都需要有。为各自的成员函数服务。也为外部的使用提供服务。
匚匚 2011-03-11
  • 打赏
  • 举报
回复
template <typename U>
std::ostream& operator<<(std::ostream& out,const clist<U>& lst)
{
out<<lst.get_val(lst.begin());
return out;
}
template <typename T>
typename clist<T>::Iterator::reference clist<T>::Iterator::operator*()const
{
return ptr->val;
}
template <typename T>
typename clist<T>::Iterator& clist<T>::Iterator::operator++()
{
ptr=ptr->next;
return *this;
}
template <typename T>
typename clist<T>::Iterator& clist<T>::Iterator::operator++(int)
{
Iterator iter=*this;
++ *this;
return iter;
}

template <typename T>
bool clist<T>::Iterator::operator ==(const clist<T>::Iterator& iter) const
{
return (ptr==iter.ptr);
}
template <typename T>
bool clist<T>::Iterator::operator!=(const clist<T>::Iterator& iter) const
{
return (ptr!=iter.ptr);
}

template <typename T>
bool clist<T>::Iterator::operator! ()const
{
return (ptr==NULL);
}

template <typename T>
bool clist<T>::Iterator::operator==(clist<T>::Iterator::link_type node) const
{
return (ptr==node);
}
template <typename T>
bool clist<T>::Iterator::operator!=(clist<T>::Iterator::link_type node) const
{
return (ptr!=node);
}
template <typename T>
typename clist<T>::Iterator::link_type clist<T>::Iterator::operator-> () const
{
return ptr;
}

template <typename T>
clist<T>::clist()
{
front=rear=NULL;
_size=0;
}
template <typename T>
clist<T>::clist(T arr[],const size_t& n)
{
for(size_t i = 0; i < n; ++i)
{
push_head(arr[i]);
}
_size = n;
}

template <typename T>
void clist<T>::destroy()
{
while(front!=NULL)
{
lnode* tmp=front->next;
delete front;
front=tmp;
}
rear=NULL;
}

template <typename T>
clist<T>::~clist()
{
destroy();
}

template <typename T>
typename clist<T>::Iterator clist<T>::begin() const
{
return Iterator(front);
}

template <typename T>
typename clist<T>::Iterator clist<T>::end() const
{
return Iterator(rear);
}

template <typename T>
typename clist<T>::size_type clist<T>::size()const
{
return _size;
}

template <typename T>
const typename clist<T>::Iterator& clist<T>::findpre(const T& val)const
{
if(front==NULL || front->val==val)
return Iterator();
const lnode* tmp=front;
while(tmp->next!=NULL && tmp->next->val!=val)
{
tmp=tmp->next;
if(tmp==NULL )
break;
}
return Iterator(tmp);
}

template <typename T>
void clist<T>::push_back(const T& val)
{
lnode* tmp=new lnode;
tmp->val=val;
tmp->next=NULL;
if(rear==NULL)
rear=front=tmp;
else
{
rear->next=tmp;
rear=tmp;
}
++_size;
}

template <typename T>
void clist<T>::push_next(const T& val,const clist<T>::Iterator& iter)
{
lnode* tmp=new lnode;
tmp->val=val;
if(iter.ptr==NULL) //findpre在两种情况下返回NULL:无或在头部
{
if(rear==NULL) //空链表
{
tmp->next=NULL;
rear=front=tmp;
}
else //插在头部的后面
{
if((tmp->next=front->next)==NULL)
rear=tmp;
front->next=tmp;

}
}
else
{
if((tmp->next=iter.ptr->next)==NULL)
rear=tmp;
iter.ptr->next=tmp;
}
++_size;
}

template <typename T>
void clist<T>::push_front(const T& val,const clist<T>::Iterator& iter)
{
if(iter.ptr==front)
{
lnode* tmp=new lnode;
tmp->val=val;
if((tmp->next=front)==NULL)
rear=tmp;
front=tmp;
++_size;
}
else
{
Iterator tmp=findpre(iter.ptr->val);
push_next(val,tmp);
}
}

template <typename T>
void clist<T>::pop_head()
{
if(front==NULL)
return;
lnode* tmp=front->next;
delete front;
if((front=tmp)==NULL)
rear=NULL;
--_size;
}

template <typename T>
void clist<T>::pop_next(const clist<T>::Iterator& iter)
{
if(iter.ptr==rear) return;
if(iter.ptr==NULL)
{
if(front==rear) return;
lnode* tmp=front->next->next;
delete front->next;
if((front->next=tmp)==NULL)
rear=front;
}
else
{
lnode* tmp=iter.ptr->next->next;
delete iter.ptr->next;
if((iter.ptr->next=tmp)==NULL)
rear=iter.ptr;
}
--_size;
}

template <typename T>
int clist<T>::pop_val(const T& val)
{
if(front==NULL) return 0;//空链表

clist<T>::Iterator iter=findpre(val);
if(iter.ptr==rear)
return 0; //未找到
if(iter.ptr==NULL) //在头部
pop_head();
else
pop_next(iter);
return 1;
}

template <typename T>
void clist<T>::pop_all()
{
destroy();
_size=0;
}
template <typename T>
void clist<T>::edit(const clist<T>::Iterator& iter,T& val)
{
iter.ptr->val=val;
}
匚匚 2011-03-11
  • 打赏
  • 举报
回复
感觉迭代器中的类型提取语句与clist<T>中的类型提取语句重复,可否将迭代器中的删除,只在clist<T>中设置?

但好像说有个约定:要设置在嵌套类中?
匚匚 2011-03-11
  • 打赏
  • 举报
回复
/*默认情况下在尾部插入,在头部删除*
*也支持在任何位置的插入.删除操作*
*/
一个自定义的list容器
template <typename T>
class clist
{
public:
clist();
clist(T [],const size_t&); //初始化为含N个元素
~clist();
class Iterator;
typedef typename Iterator::value_type value_type;
typedef typename Iterator::pointer pointer;
typedef typename Iterator::reference reference;
typedef typename Iterator::size_type size_type;
Iterator begin() const;
Iterator end() const;
reference get_val(const Iterator& val)const{return val.ptr->val;}
void push_back(const T&); //在尾部增加元素
void push_next(const T&,const Iterator&); //在指定位置的后面增加元素
void push_front(const T&,const Iterator&);//在指定位置的前面增加元素
void pop_head(); //删除头元素
int pop_val(const T&); //删除指定元素
void pop_all(); //全部删除
size_type size()const;
void edit(const Iterator&,T&); //修改元素值

template <typename U> //修改元素的成员值
void edit(const Iterator&,U,int,void (*)(const Iterator&,U,int));

clist<T>& operator=(const T& val){push_back(val);return *this;}

template <typename U>
friend std::ostream& operator<<(std::ostream& out,const clist<U>& lst);
/*friend std::ostream& operator<<(std::ostream& out,const clist& lst)
{
return out<<lst.get_val(lst.begin());
// 相当定义了一个全局函数,不是成员函数
}*/
/*friend std::ostream& operator<< <>(std::ostream& out,const clist<T>& lst);
*可不要后面的<T> 也可在前面的<>中加入T
*/
protected:
typedef typename Iterator::link_type link_type;
private:
const Iterator& findpre(const T&)const; //返回要查找元素的前一节点
void pop_next(const Iterator&); //删除下一位置的元素
void destroy(); //销毁
struct lnode
{
lnode* next;
T val;
};
lnode* front;
lnode* rear;
size_t _size;
};

template <typename T>
class clist<T>::Iterator
{
public:
typedef T value_type;
typedef T* pointer;
typedef T& reference;
typedef lnode* link_type;
typedef size_t size_type;

link_type ptr;

Iterator(link_type front=NULL):ptr(front){}
reference operator*()const;
Iterator& operator++();
Iterator& operator++(int);
bool operator==(const Iterator& iter) const;
bool operator!=(const Iterator&) const;
bool operator!() const;
bool operator==(link_type) const;
bool operator!=(link_type) const;
link_type operator-> () const;
};
pengzhixi 2011-03-11
  • 打赏
  • 举报
回复
是否设置为私有不重要了。
因为Iterator::operator-> 就已经暴露了Iterator的一个实现了。
匚匚 2011-03-11
  • 打赏
  • 举报
回复
感觉这里应该增加接口。另,是否将迭代器的数据成员设为私有的?

#ifndef STU_H_
#define STU_H_
template <typename T=std::string,typename U=int,typename I=float>
struct node
{
node(){}
node(T name,T sex,U id,I ave)
{
_name=name;_sex=sex;_id=id;_ave=ave;
}
void set_name(T& other){_name=other;}//修改相应成员,下同
void set_sex(T& other){_sex=other;} //
void set_id(U& other){_id=other;} //
void set_ave(I& other){_ave=other;} //
T _name;
T _sex;
U _id;
I _ave;
template <typename A,typename B,typename C>
friend std::istream& operator>>(std::istream&,node<A,B,C>&);

template <typename A,typename B,typename C>
friend std::ostream& operator<<(std::ostream&,const node<A,B,C>&);
};
template <typename T,typename U,typename I>
std::istream& operator>>(std::istream& in,node<T,U,I>& n)
{
std::cout<<"依次输入姓名/性别/学号/成绩:";
in>>n._name>>n._sex>>n._id>>n._ave;
return in;
}
template <typename T,typename U,typename I>
std::ostream& operator<<(std::ostream& out,const node<T,U,I>& n)
{
out<<"姓名:"<<n._name<<'\n'
<<"性别:"<<n._sex<<'\n'
<<"学号:"<<n._id<<'\n'
<<"成绩:"<<n._ave<<'\n';
return out;
}

#endif //STU_H_

shaotine_wu 2011-03-11
  • 打赏
  • 举报
回复
没看明白
Defonds 2011-03-11
  • 打赏
  • 举报
回复
代码好长,直接贴错误信息
pengzhixi 2011-03-11
  • 打赏
  • 举报
回复
typename clist<T>::Iterator iter=findpre(val);
另外你的问题在哪
匚匚 2011-03-11
  • 打赏
  • 举报
回复
请问,我这里面有哪些是该隐藏保护而没有这样做的?
pengzhixi 2011-03-11
  • 打赏
  • 举报
回复
额,不同类中定义的类型是不一样的。这个和我这个类型被用到哪没什么直接关系。

因为你的iterator里面有用到node,那么在iterator里面使用node里面定义的类型这个无可厚非。
qq120848369 2011-03-10
  • 打赏
  • 举报
回复
悲剧的就是你的iterator竟然没有模板,这很诡异了.

接口不好,直接Iterator即可,const Iterator是很诡异的东西.
pengzhixi 2011-03-10
  • 打赏
  • 举报
回复
告诉我你的Iterator怎么定义的,主要作用是什么。
匚匚 2011-03-10
  • 打赏
  • 举报
回复
春天里
匚匚 2011-03-10
  • 打赏
  • 举报
回复
望大家不吝赐教

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧