普通函数指针: "return_type (*ptr_name)(para_types) "
类成员函数指针: "return_type (class_name::*ptr_name)(para_types)"
类数据成员指针: "type class_name::* ptr_name";
C/C++:
class Demo
{
public:
Demo():data()
{ }
int data;
int show(int a,int b)
{
return a+b;
}
}; int main(int argc, char **argv)
{
Demo A;
Demo* B=new Demo;
//完成声明和赋值
int Demo::* int_ptr=&Demo::data;
//赋值完后没有数据信息,需要对象解引用获得数据
std::cout<<A.*int_ptr<<std::endl;
std::cout<<B->*int_ptr<<std::endl; //类成员函数指针
int (Demo::*ptr)(int,int)=&Demo::show;
std::cout<<(A.*ptr)(,)<<std::endl; return ;
}
STL算法有时需要使用类成员的函数,然而类成员函数指针不是可调用对象,functor<> bind mem_fn 各自方式不一,但是内部都是隐式传递this指针通过解引用来获取数据或调用函数
C/C++扩展:
//成员函数指针使用 class Screen
{
public:
enum ACTION
{
Up_, Down_, Left_, Right_
}; Screen() = default; Screen &Move(ACTION para)
{
return (this->*Menu[para])();
} private:
using Action=
Screen &(Screen::*)(); static Action Menu[]; Screen &Up()
{
std::cout << "Up" << std::endl;
return *this;
} Screen &Down()
{
std::cout << "Down" << std::endl;
return *this;
} Screen &Left()
{
std::cout << "Left" << std::endl;
return *this;
} Screen &Right()
{
std::cout << "Right" << std::endl;
return *this;
} }; Screen::Action Screen::Menu[]{&Screen::Up, &Screen::Down, &Screen::Left, &Screen::Right}; int main()
{
Screen obj;
obj.Move(Screen::Up_);
obj.Move(Screen::Down_);
obj.Move(Screen::Left_);
obj.Move(Screen::Right_);
obj.Move(Screen::Right_); return ;
} #include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
#include <string> //类成员函数指针不是可调用对象,一般STL算法需要包装类成员函数指针为可调用对象
//这三种封装方式都是内部通过获得容器返回的对象, ".*" / "->*" 来调用;
//1.std::function<成员函数类型(第一个参数设置为对象本身类型)> fcn=&std::xxxx::xxx; 区别: 第一个参数是传入对象类型,根据容器是引用还是指针选择(.* / ->*)
//2.std::bind(&std::string::empty,std::placeholders::_1) 区别:可通过指针或者对象执行成员函数;
//3.std::mem_fn(&std::string::empty) C++11, 区别:可通过指针和对象执行成员函数
//4.可使用lamda调用; class Str
{
public:
std::string str; Str(const std::string &str_) : str(str_)
{ } Str(const char *str_) : str(str_)
{ } bool empty() const noexcept
{
return str.empty();
}
}; int main()
{ std::vector<Str> str_vec{"xa", "sad", "", "", "", "qqewhegr", "aqdq"}; std::function<bool(const Str &)> fn = &Str::empty; std::size_t empty_size_function=std::count_if(str_vec.begin(),str_vec.end(),fn); std::size_t empty_size_bind=std::count_if(str_vec.begin(),str_vec.end(),std::bind(&Str::empty,std::placeholders::_1)); std::size_t empty_size_mem_fn=std::count_if(str_vec.begin(),str_vec.end(),std::mem_fn(&Str::empty)); std::cout << empty_size_function << std::endl;
std::cout << empty_size_bind << std::endl;
std::cout << empty_size_mem_fn << std::endl; std::size_t size = std::count_if(str_vec.begin(), str_vec.end(), [](const Str& str) { return str.empty(); });
std::cout << size << std::endl; return ;
}