当变量类型为复合型态时,如何重载List的函数,来实现排序查找移除等功能?

zlxadhkust 2009-04-14 03:29:18
加精
我已完成如下头文件:

#ifndef FRAME_H_
#define FRAME_H_

#include <list>
using namespace std;

typedef struct
{
unsigned long int num; // number of frame
double len_Ratio; // parameters within this frame
double angle; //

}
FRAME;

class FrameInfo
{

private:

FRAME FRMtemp;
list< FRAME > FrmList;
list<FRAME>::iterator pos;

public:

FrameInfo();
~FrameInfo();

};

#endif

问题即是:我的这个FrameInfo类实现的功能是用list保存关于一个动画的帧信息。它要实现对这个FrmList进行排序,插入,移除等功能。
具体讲就是sort(),remove_if(), find_if()等函数,需要写一个仿函数或者重载less<>等来实现,所有这些操作都是根据帧编号num来做的。
不知道具体怎么做,查了MSND,写的云里雾里的看不懂。
请高手帮忙!

...全文
597 35 打赏 收藏 转发到动态 举报
写回复
用AI写文章
35 条回复
切换为时间正序
请发表友善的回复…
发表回复
s_xgwang 2009-04-19
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 leo315 的回复:]
mark
[/Quote]

问题出自些处:
FRAMEINFO * Frame::GetFrame(unsigned int num) const //-->
{

using std::map;
FRAMEMAP::iterator pos; //-->此迭代器是可以修改 FrmMap 的值的,而你函数定义为 const 关键字
//保持类成员不变。编译器在编译时,对 STL 的安全性要求较高,像这种有二义性的,是不会通过编译的。
pos = FrmMap.find(num);
}
zlxadhkust 2009-04-19
  • 打赏
  • 举报
回复
对了,后来我发现有些写法也是不行的,比如:

先声明iterator:


FRAMEMAP::const_iterator pos;


然后,这样给它赋值:

pos = FrmMap.begin()+1;

或者:

(pos+1)->first........

这类语法都不能通过编译,然而pos++这样是可以的。
zlxadhkust 2009-04-19
  • 打赏
  • 举报
回复
楼上的回答应该是正解。
yuzhigen 2009-04-17
  • 打赏
  • 举报
回复
wftcujln??
门后面的猫 2009-04-17
  • 打赏
  • 举报
回复
顶一下,支持
jiawu1894 2009-04-16
  • 打赏
  • 举报
回复
挺好的
insulted 2009-04-16
  • 打赏
  • 举报
回复
偶来学习!
zlxadhkust 2009-04-16
  • 打赏
  • 举报
回复
虽然最后我解决了问题,但是只是在实践上解决,不是原理上,因为仍旧有些现象不知其原因所在,以下是最后的代码,为了方便比较,我将再发一次我在24楼发过的代码,就是前面那部分没有使用类的程序的代码。

这是没有使用类的:


#include <iostream>
#include <algorithm>
#include <map>
using namespace std;

typedef struct
{
double len_Ratio; // parameters within this frame
double angle; //
}
FRAMEINFO;

typedef unsigned int UNIN;

int main()
{
typedef map<UNIN,FRAMEINFO> FRAME;
FRAME coll;
FRAME::iterator pos; // 请注意这里!!!

FRAMEINFO temp;

temp.angle = 80;
temp.len_Ratio = 0.36;

coll[1]=temp;

temp.angle = 360;
temp.len_Ratio = 0.46;

coll[2]=temp;

temp.angle = 270;
temp.len_Ratio = 0.66;

coll[3]=temp;

pos = coll.find (3); // logarithmic complexity

if (pos != coll.end())
{
cout << pos->first << ": "
<< pos->second.angle << " :"
<< pos->second.len_Ratio
<< endl;
}

for (pos = coll.begin(); pos != coll.end(); ++pos)
{
cout << ' '
<< pos->first << ": " << endl
<< "Angle: "<< pos->second.angle << "-"
<< "Length Ratio: "<< pos->second.len_Ratio
<< endl;
}

cout << endl;

temp.angle = 60;
temp.len_Ratio = 0.96;

coll[2]=temp;

for (pos = coll.begin(); pos != coll.end(); ++pos)
{
cout << ' '
<< pos->first << ": " << endl
<< "Angle: "<< pos->second.angle << "-"
<< "Length Ratio: "<< pos->second.len_Ratio
<< endl;
}

cout << endl;

return 0;
}


这个程序可以无误的运行。

下面是用类来封装map操作的程序代码:

Frame.h:


#ifndef FRAME_H_
#define FRAME_H_

#include <iostream>
#include <algorithm>
#include <map>
using namespace std;

#define NULL 0;

typedef struct
{
double len_Ratio; // parameters within this frame
int angle; //
}
FRAMEINFO;

typedef map<unsigned int,FRAMEINFO> FRAMEMAP;

class Frame
{
private:

FRAMEINFO frminfo;
FRAMEMAP FrmMap;
FRAMEMAP::const_iterator curpos;

public:

Frame();
~Frame();
const FRAMEINFO * GetFrame(unsigned int) const;
void RemoveFrame(unsigned int);
void AddFrame(unsigned int, FRAMEINFO &);
void UpdateFrmInfo(unsigned int, FRAMEINFO &);
void PrintAll();
};

#endif



Frame.cpp:



#include "Frame.h"

Frame::Frame()
{

}

Frame::~Frame()
{

}

const FRAMEINFO * Frame::GetFrame(unsigned int num) const
{


FRAMEMAP::const_iterator pos = FrmMap.find(num); // 请注意这里!! 如果这里没有加const_,即与上一个程序写法一致,那么
// 所有关于pos的赋值和比较操作都将被报错。
if (pos != FrmMap.end())
{
return &(pos->second);
}

else
return NULL;

}

void Frame::AddFrame(unsigned int num, FRAMEINFO & fi)
{
FRAMEINFO temp = fi;
FrmMap[num]=temp;

}

void Frame::RemoveFrame(unsigned int num)
{
FrmMap.erase(num);
}

void Frame::UpdateFrmInfo(unsigned int num, FRAMEINFO & fi)
{
FrmMap[num]=fi;
}

void Frame::PrintAll()
{
FRAMEMAP::const_iterator pos;
for(pos=FrmMap.begin();pos!=FrmMap.end();pos++)
{
cout << "angle: " << pos->second.angle << endl
<< "leng ratio: " << pos->second.len_Ratio << endl;
}

}


main.cpp


#include "Frame.h"

int main()
{
FRAMEINFO fi_1;
FRAMEINFO fi_2;
FRAMEINFO fi_3;
FRAMEINFO fi_4;
FRAMEINFO fi_5;
FRAMEINFO fi_6;
FRAMEINFO fi_7;

FRAMEINFO fi_temp;

fi_1.angle = 23;
fi_1.len_Ratio = 0.21;

fi_2.angle = 24;
fi_2.len_Ratio = 0.22;

fi_3.angle = 25;
fi_3.len_Ratio = 0.23;

fi_4.angle = 26;
fi_4.len_Ratio = 0.24;

fi_5.angle = 27;
fi_5.len_Ratio = 0.25;

fi_6.angle = 28;
fi_6.len_Ratio = 0.26;

fi_7.angle = 29;
fi_7.len_Ratio = 0.27;


Frame f;

f.AddFrame(24, fi_1);
f.AddFrame(48, fi_2);
f.AddFrame(56, fi_3);
f.AddFrame(60, fi_4);
f.AddFrame(78, fi_5);
f.AddFrame(102, fi_6);
f.AddFrame(112, fi_7);

f.PrintAll();

fi_temp = * (f.GetFrame(60));

cout << fi_temp.angle << endl
<< fi_temp.len_Ratio << endl;

FRAMEINFO fi_temp_2;
fi_temp_2.angle = 340;
fi_temp_2.len_Ratio = 2.0;

f.UpdateFrmInfo(60, fi_temp_2);

fi_temp = * (f.GetFrame(60));

cout << fi_temp.angle << endl
<< fi_temp.len_Ratio << endl;

f.RemoveFrame(60);
f.PrintAll();
return 0;
}


现在这个程序也可以无误运行。

至于前面讨论的关于list的仿函数和函数适配器的那些问题,由于时间原因,我没有再去试验。以后若有时间,再重新研究一下这个问题,再来这里跟大家分享结果。感谢各位的关注与帮助。我打算就此结贴,但是学习没有止境,所以仍旧欢迎各位来此继续讨论这个问题。
yinzhongxiang 2009-04-16
  • 打赏
  • 举报
回复
学习 学习
gaoliuyang 2009-04-15
  • 打赏
  • 举报
回复
不会C++还是支持一下!!!
zlxadhkust 2009-04-15
  • 打赏
  • 举报
回复
我在16楼贴的代码是昨晚三归一帮我写的,但是编译的问题是:

error C2679: binary '=' : no operator defined which takes a right-hand operand of type 'class std::list<struct FRAME,class std::allocator<struct FRAME> >::const_iterator' (or there is no acce
ptable conversion)

它指向这句:

pos = find_if(FrmList.begin(), FrmList.end(), Function(the_num));

pos被我定义成一个迭代,它本质上应该是个指针,我这是仿造《C++ Standard Library, The: A Tutorial and Reference》一书中的示例写的:

list<int>::iterator pos;
pos = find_if (coll.begin(), coll.end(), //range
is Prime); //predicate
if (pos != coll.end()) {
sw8016 2009-04-15
  • 打赏
  • 举报
回复
支持一下
佳然love 2009-04-15
  • 打赏
  • 举报
回复
顶贴
zlxadhkust 2009-04-15
  • 打赏
  • 举报
回复
首先感谢各位的关注,等到这个功能的问题彻底解决了,我会结贴给大家送分。
因为关于list的问题始终没能解决,出于效率的考虑,我今天不得不换了一条路,我放弃了list,采用了map,这样就绕过了所有需要写Functor或者function adapter的麻烦,但是居然还是有问题。

先见代码:


#include <iostream>
#include <algorithm>
#include <map>
using namespace std;

typedef struct
{
double len_Ratio; // parameters within this frame
double angle; //
}
FRAMEINFO;

typedef unsigned int UNIN;

int main()
{
typedef map<UNIN,FRAMEINFO> FRAME;
FRAME coll;
FRAME::iterator pos;

FRAMEINFO temp;

temp.angle = 80;
temp.len_Ratio = 0.36;

coll[1]=temp;

temp.angle = 360;
temp.len_Ratio = 0.46;

coll[2]=temp;

temp.angle = 270;
temp.len_Ratio = 0.66;

coll[3]=temp;

pos = coll.find (3); // logarithmic complexity

if (pos != coll.end())
{
cout << pos->first << ": "
<< pos->second.angle << " :"
<< pos->second.len_Ratio
<< endl;
}

for (pos = coll.begin(); pos != coll.end(); ++pos)
{
cout << ' '
<< pos->first << ": " << endl
<< "Angle: "<< pos->second.angle << "-"
<< "Length Ratio: "<< pos->second.len_Ratio
<< endl;
}

cout << endl;

temp.angle = 60;
temp.len_Ratio = 0.96;

coll[2]=temp;

for (pos = coll.begin(); pos != coll.end(); ++pos)
{
cout << ' '
<< pos->first << ": " << endl
<< "Angle: "<< pos->second.angle << "-"
<< "Length Ratio: "<< pos->second.len_Ratio
<< endl;
}

cout << endl;

return 0;
}


以上代码在VC6.0下编译运行,没有问题。

于是我进一步,用类来封装:

Frame.h文件:

#ifndef FRAME_H_
#define FRAME_H_

#include <iostream>
#include <algorithm>
#include <map>
using namespace std;



#define NULL 0;

typedef struct
{
double len_Ratio; // parameters within this frame
int angle; //
}
FRAMEINFO;

typedef map<unsigned int,FRAMEINFO> FRAMEMAP;

class Frame
{
private:

FRAMEINFO frminfo;
FRAMEMAP FrmMap;
FRAMEMAP::iterator curpos;

public:

Frame();
~Frame();
FRAMEINFO * GetFrame(unsigned int) const;
void RemoveFrame(unsigned int);
void AddFrame(unsigned int, FRAMEINFO &);
void UpdateFrmInfo(unsigned int, FRAMEINFO &);
};

#endif


Frame.cpp文件:


#include <algorithm>
#include "Frame.h"

Frame::Frame()
{

}

Frame::~Frame()
{

}

FRAMEINFO * Frame::GetFrame(unsigned int num) const
{

using std::map;
FRAMEMAP::iterator pos;
pos = FrmMap.find(num);
if (pos != FrmMap.end())
{
return &(pos->second);
}

else
return NULL;

}

void Frame::AddFrame(unsigned int num, FRAMEINFO & fi)
{
FRAMEINFO temp = fi;
FrmMap[num]=temp;

}

void Frame::RemoveFrame(unsigned int num)
{
FrmMap.erase(num);
}

void Frame::UpdateFrmInfo(unsigned int num, FRAMEINFO & fi)
{
FrmMap[num]=fi;
}


编译出错:

e:\csit691\15thapr\frame\frame\frame.cpp(20) : error C2679: binary '=' : no operator defined which takes a right-hand operand of type 'class std::_Tree<unsigned int,struct std::pair<unsigned int const ,struct FRAMEINFO>,struct std::map<unsigned int,
struct FRAMEINFO,struct std::less<unsigned int>,class std::allocator<struct FRAMEINFO> >::_Kfn,struct std::less<unsigned int>,class std::allocator<struct FRAMEINFO> >::const_iterator' (or there is no acceptable conversion)
e:\csit691\15thapr\frame\frame\frame.cpp(21) : error C2679: binary '!=' : no operator defined which takes a right-hand operand of type 'class std::_Tree<unsigned int,struct std::pair<unsigned int const ,struct FRAMEINFO>,struct std::map<unsigned int
,struct FRAMEINFO,struct std::less<unsigned int>,class std::allocator<struct FRAMEINFO> >::_Kfn,struct std::less<unsigned int>,class std::allocator<struct FRAMEINFO> >::const_iterator' (or there is no acceptable conversion)
Error executing cl.exe.

错误指向pos相关的操做,这样一来,我发现问题似乎又跟list的情况一样了。

是不是编译器出了什么问题或者哪里设置的有问题~~~
leo315 2009-04-15
  • 打赏
  • 举报
回复
mark
GUZHUANQI 2009-04-15
  • 打赏
  • 举报
回复
这个好难啊!!!我来错了`````````````
a727128806 2009-04-15
  • 打赏
  • 举报
回复
1
zlxadhkust 2009-04-14
  • 打赏
  • 举报
回复
Frame.h:


#ifndef FRAME_H_
#define FRAME_H_

#include <list>
#include <algorithm>
#include <functional>

using namespace std;

typedef struct
{
unsigned long int num; // number of frame
double len_Ratio; // parameters within this frame
double angle; //
/*
static bool is_the_frame(const int & the_num)
{
return (num == the_num);
}
*/
}
FRAME;

struct Function : public unary_function <FRAME, bool>
{
Function(unsigned long n)
{
num = n;
}
bool operator()( FRAME& right) const
{
return num == right.num;
}
unsigned long num;
};

bool less_num(const FRAME & f1, const FRAME & f2)
{
return (f1.num < f2.num);
}
/*
bool is_the_frame(const FRAME & the_frame, const int & the_num)
{
return (the_frame.num == the_num);
}



class IsFrame

{

private:

FRAME frm;

public:

IsFrame(const FRAME & f) : frm(f) {}

static bool Equ(const unsigned long & num) { return frm.num == num; }

};

*/

class FrameInfo
{

private:

unsigned long int num_temp;
FRAME FRMtemp;
list<FRAME> FrmList;
list<FRAME>::iterator pos;
//FRAME * pos;

public:


FrameInfo();
~FrameInfo();

FRAME & GetFrame(unsigned long int) const;
void RemoveFrame(unsigned long int);
void SortFrame();
void AddFrame(FRAME & frame);
void FillStateArr() const;

};



#endif


Frame.cpp


#include "Frame.h"

FrameInfo::FrameInfo()
{

}

FrameInfo::~FrameInfo()
{

}

FRAME & FrameInfo::GetFrame(unsigned long the_num) const
{
//pos = find_if(FrmList.begin(), FrmList.end(), bind2nd(is_the_frame(), the_num));

/*
if(! FrmList.empty())
{
pos = find_if(FrmList.begin(), FrmList.end(), Function(the_num));
}
return * pos;
*/
for(pos = FrmList.begin(); pos = FrmList.end(); ++pos)
{
if(pos->num == the_num)
{

return *pos;
}
}

return NULL;

}

void FrameInfo::RemoveFrame(unsigned long int the_num)
{

//pos = find_if(FrmList.begin(), FrmList.end(), bind2nd(is_the_frame(), the_num));

//FrmList.erase (pos);

FrmList.remove_if ( Function(the_num) );


}

void FrameInfo::SortFrame()
{
sort(FrmList.begin(), FrmList.end(), less_num);
}

void FrameInfo::AddFrame(FRAME & frame)
{
FrmList.push_back(frame);
}
zlxadhkust 2009-04-14
  • 打赏
  • 举报
回复
zhh157

能否解释下你的这段代码呢:

class ListItemEqual
{
public:
ListItemEqual( const unsigned long id ):compare_id( id ) {}
ListItemEqual( const FRAME& f ): compare_id( f.num ) {}
~ListItemEqual(){}

bool operator() ( const FRAME& f )
{
return f.num == compare_id;
}
private:
unsigned long compare_id;
};


我觉得可能你的写法是能解决问题的。之前那样定义is_the_frame()应该是不行的。
old-six-programmer 2009-04-14
  • 打赏
  • 举报
回复
考虑到效率,尽量使用list的成员函数
包括sort, remove, remove_if, unique, reverse

上面我写错了,list好像并无find_if成员函数,应该使用算法
加载更多回复(13)

65,211

社区成员

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

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