背景:
在做课程设计时,遇到一个问题,需要根据类型查找某个File的名称。处理了一段时间后,没有解决。终于找到了。记录下来
所谓函子,就是C++对C语言的函数指针的封装。即“()”函数调用者的重载。说白了,函数调用操作符()实际上是代替了函数指针,调用了重载的()对应的已定义函数。 () 运算符只能在类中重载。
我们来看一下现场:
如果只是找对象的某种基本数据类型,直接找就可以了。
int main()
{
vector<int>v;
v.push_back(1);
v.push_back(2);
auto it=find(v.begin(),v,end(),2);
if(it==v.end()){
cout<<"not find"<<endl;
}
else{
cout<<*it<<endl;
}
}
现在,例如,如果我的容器中存储了一个对象,那么如果我想找到它,我需要重载 == 来告诉编译器找到对象相等的规则。
struct Person{
Person(){}
Person(int _name,int _age)
:name(_name),
age(_age)
{ }
bool operator==(const Person& p) const{
return name==p.name;
}
int name;
int age;
}
int main()
{
vector<int>v;
v.push_back(Person("张三",18));
v.push_back(Person("李四",19));
Person cp_to_find; // 要查找的对象
cp_to_find.name="张三";
auto it=find(v.begin(),v,end(),cp_to_find);
if(it==v.end()){
cout<<"not find"<<endl;
}
else{
cout<<*it<<endl;
}
}
那么现在我的类中有这个类型的指针,我该如何找到它呢?
其中的每个元素都是一个指向对象的指针。我们想检查一下
查找具有指定文件名的元素,并获取指向该对象的指针(如果找到)。
需要比较的不仅仅是类型相等,还需要比较两个对象的指针对应的值。
这里需要用到。
我们需要使用函数并自己指定谓词函数(即函数的第三个参数,请查阅STL手册)。我们先看一下函数的定义:
InputIterator find_if(InputIterator _First, InputIterator _Last, Predicate _Pred);
Parameters
_First
An input iterator addressing the position of the first element in the range to be searched.
_Last
An input iterator addressing the position one past the final element in the range to be searched.
_Pred
User-defined predicate function object that defines the condition to be satisfied by the element being searched for. A predicate takes single argument and returns true or false.
这里使用了函子。
我们在 File 类外部定义结构,并在指针指向的更具体的元素内部执行函数重载。
typedef struct finder_t
{
finder_t(string _name)
:name(_name)
{}
//重载()--->cpp的仿函数代替函数指针
bool operator()(File* f)
{
return (name == f->File_name);
}
string name;
}finder_t;
然后你可以使用该函数来查找:
struct File {
File() {}
File(const string& _File_name , string _path="" , File* _parent=nullptr, vector<File*> _File_context=vector<File*>() )
:File_name(_File_name),
path(_path),
parent(_parent),
File_context(_File_context)
{}
char File_type;//文件类型
string File_owner;//文件拥有者
string File_ownergroup;//文件拥有组
unsigned size;//文件大小
string _time;//创建时间
string File_name;//文件名
string contain;//文件内容
File* parent;//父级文件(目录)
vector<File*> File_context;//文件(目录)列表
string path;//文件路径
};
typedef struct finder_t
{
finder_t(string _name)
:name(_name)
{}
//重载()--->cpp的仿函数代替函数指针
bool operator()(File* f)
{
return (name == f->File_name);
}
string name;
}finder_t;