zoukankan      html  css  js  c++  java
  • C/C++ 类成员函数指针 类成员数据指针

    普通函数指针:  "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 }
  • 相关阅读:
    节点和坐标系
    精灵类
    导演类
    部分辅助宏
    妥善使用autorelease()方法
    内存管理笔记
    向eclipse中的项目导入jar包(作为library引用和放入web-inf/lib下的两种方法和区别)
    Request processing failed; nested exception is java.lang.NullPointerException
    getRequestURI、getReuqestURL的区别【转】
    tomcat部署javaWeb项目,界面样式都没有加载
  • 原文地址:https://www.cnblogs.com/xuaidongstdudyrecording/p/7256083.html
Copyright © 2011-2022 走看看