普通函数指针: "return_type (*ptr_name)(para_types) "
类成员函数指针: "return_type (class_name::*ptr_name)(para_types)"
类数据成员指针: "type class_name::* ptr_name";
C/C++:
1 class Demo 2 { 3 public: 4 Demo():data(100) 5 { 6 7 } 8 int data; 9 int show(int a,int b) 10 { 11 return a+b; 12 } 13 }; 14 15 16 17 int main(int argc, char **argv) 18 { 19 Demo A; 20 Demo* B=new Demo; 21 //完成声明和赋值 22 int Demo::* int_ptr=&Demo::data; 23 //赋值完后没有数据信息,需要对象解引用获得数据 24 std::cout<<A.*int_ptr<<std::endl; 25 std::cout<<B->*int_ptr<<std::endl; 26 27 28 //类成员函数指针 29 int (Demo::*ptr)(int,int)=&Demo::show; 30 std::cout<<(A.*ptr)(1,2)<<std::endl; 31 32 return 0; 33 }
STL算法有时需要使用类成员的函数,然而类成员函数指针不是可调用对象,functor<> bind mem_fn 各自方式不一,但是内部都是隐式传递this指针通过解引用来获取数据或调用函数
C/C++扩展:
1 //成员函数指针使用 2 3 class Screen 4 { 5 public: 6 enum ACTION 7 { 8 Up_, Down_, Left_, Right_ 9 }; 10 11 Screen() = default; 12 13 Screen &Move(ACTION para) 14 { 15 return (this->*Menu[para])(); 16 } 17 18 private: 19 using Action= 20 Screen &(Screen::*)(); 21 22 23 static Action Menu[]; 24 25 Screen &Up() 26 { 27 std::cout << "Up" << std::endl; 28 return *this; 29 } 30 31 Screen &Down() 32 { 33 std::cout << "Down" << std::endl; 34 return *this; 35 } 36 37 Screen &Left() 38 { 39 std::cout << "Left" << std::endl; 40 return *this; 41 } 42 43 Screen &Right() 44 { 45 std::cout << "Right" << std::endl; 46 return *this; 47 } 48 49 }; 50 51 Screen::Action Screen::Menu[]{&Screen::Up, &Screen::Down, &Screen::Left, &Screen::Right}; 52 53 54 int main() 55 { 56 Screen obj; 57 obj.Move(Screen::Up_); 58 obj.Move(Screen::Down_); 59 obj.Move(Screen::Left_); 60 obj.Move(Screen::Right_); 61 obj.Move(Screen::Right_); 62 63 64 return 0; 65 } 66 67 68 69 #include <iostream> 70 #include <vector> 71 #include <functional> 72 #include <algorithm> 73 #include <string> 74 75 //类成员函数指针不是可调用对象,一般STL算法需要包装类成员函数指针为可调用对象 76 //这三种封装方式都是内部通过获得容器返回的对象, ".*" / "->*" 来调用; 77 //1.std::function<成员函数类型(第一个参数设置为对象本身类型)> fcn=&std::xxxx::xxx; 区别: 第一个参数是传入对象类型,根据容器是引用还是指针选择(.* / ->*) 78 //2.std::bind(&std::string::empty,std::placeholders::_1) 区别:可通过指针或者对象执行成员函数; 79 //3.std::mem_fn(&std::string::empty) C++11, 区别:可通过指针和对象执行成员函数 80 //4.可使用lamda调用; 81 82 83 class Str 84 { 85 public: 86 std::string str; 87 88 Str(const std::string &str_) : str(str_) 89 { 90 91 } 92 93 Str(const char *str_) : str(str_) 94 { 95 96 } 97 98 bool empty() const noexcept 99 { 100 return str.empty(); 101 } 102 }; 103 104 105 int main() 106 { 107 108 std::vector<Str> str_vec{"xa", "sad", "", "", "", "qqewhegr", "aqdq"}; 109 110 111 std::function<bool(const Str &)> fn = &Str::empty; 112 113 std::size_t empty_size_function=std::count_if(str_vec.begin(),str_vec.end(),fn); 114 115 std::size_t empty_size_bind=std::count_if(str_vec.begin(),str_vec.end(),std::bind(&Str::empty,std::placeholders::_1)); 116 117 std::size_t empty_size_mem_fn=std::count_if(str_vec.begin(),str_vec.end(),std::mem_fn(&Str::empty)); 118 119 120 std::cout << empty_size_function << std::endl; 121 std::cout << empty_size_bind << std::endl; 122 std::cout << empty_size_mem_fn << std::endl; 123 124 125 126 std::size_t size = std::count_if(str_vec.begin(), str_vec.end(), [](const Str& str) { return str.empty(); }); 127 std::cout << size << std::endl; 128 129 130 return 0; 131 }
时间: 2024-10-26 19:43:12