精华内容
下载资源
问答
  • 对于指向类成员指针,必须紧记,指向类成员(非static)的指针并非指针
  • 类成员函数我们也可以相似的认为,它是指向同类中同一组类型的成员函数的指针,当然这里的成员函数更准确的讲应该是指非静态的成员函数。前者是直接指向函数地址的,而后者我们从字面上也可以知道 它肯定是跟类和...
  • C++ 指向类成员指针

    2020-12-20 19:10:14
    前面曾写过一篇恼人的函数指针(一...简单的讲,指向类成员函数的指针与普通函数指针的区别在于,前者不仅要匹配函数的参数类型和个数以及返回值类型,还要匹配该函数指针所属的类类型。总结一下,比较以下几点: a)参
  • 指向类成员函数指针并非指针

    千次阅读 2007-03-19 15:59:00
    参考>的相关章节"指向类成员函数指针",这个术语中包含了"类成员函数"的术语,但是严格的说,这里的成员函数只是指非静态成员函数,这个术语中还包含了"指针"这个术语,但是严格的说,它即不包含地址,行为也不象指针,说...

    参考<<C++必知必会>>的相关章节
    "指向类成员函数的指针",这个术语中包含了"类成员函数"的术语,但是严格的说,这里的成员函数只是指非静态成员函数,这个术语中还包含了"指针"这个术语,
    但是严格的说,它即不包含地址,行为也不象指针,说得干脆点,那就是"指向类成员函数的指针"并非指针.尽管这个术语有很大的迷惑性,但是就其含义来说,
    可以把一组同类型的函数抽象为一个"指向函数的指针",同样的道理,可以把一组类中同类型的类成员函数抽象为一个"指向类成员函数的指针",两者是一致的
    "指向类成员函数的指针"和"指向函数的指针"有什么区别?从字面上就可以清楚的知道,前者是和类,对象相关的,而后者直接指向函数的地址

    我们首先复习一下"指向函数的指针"如何使用?
    void print()
    {
    }

     void (*pfun)(); //声明一个指向函数的指针,函数的参数是void,函数的返回值是void
     pfun = print;  //赋值一个指向函数的指针
     (*pfun)();   //使用一个指向函数的指针

    比较简单,不是吗?为什么*pfun需要用()扩起来呢?因为*的运算符优先级比()低,如果不用()就成了*(pfun())

    "指向类成员函数的指针"比"指向函数的指针"就多了个类的区别:

    struct CPoint
    {
     void plus(double x_, double y_)
     {
     }
     void minus(double x_, double y_)
     {
     }
     void mul(double x_, double y_)
     {
     }
     void dev(double x_, double y_)
     {
     }

     virtual void move(double x_, double y_)
     {

     }
     double x;
     double y;
    };

    void Oper(CPoint* pPoint, void (CPoint::*pfun)(double x_, double y_), int x, int y)
    {
     (pPoint->*pfun)(x, y);
    }

    struct CPoint3d : public CPoint
    {
     void move(double x_, double y_)
     {

     }
    };

    int main(int argc, char* argv[])
    {
     CPoint pt;
     void (CPoint::*pfun)(double x_, double y_);
     int offset = 0;

     pfun = &CPoint::plus;
     offset = (int&)pfun;
     (pt.*pfun)(10, 10);
     Oper(&pt, pfun, 10, 10);

     pfun = &CPoint::minus;
     offset = (int&)pfun;
     (pt.*pfun)(10, 10);
     Oper(&pt, pfun, 10, 10);
     
     pfun = &CPoint::move;
     offset = (int&)pfun;
     (pt.*pfun)(10, 10);
     Oper(&pt, pfun, 10, 10);

     CPoint3d pt3d;
     void (CPoint3d::*p3dfun)(double x_, double y_);
     p3dfun = &CPoint3d::move;
     (pt3d.*p3dfun)(10, 10);

     //p3dfun = pfun; //正确
     //pfun = p3dfun; //错误
     pfun = (void (CPoint::*)(double, double))p3dfun;

     Oper(&pt3d, (void (CPoint::*)(double, double))p3dfun, 10, 10);
     
     return 0;
    }

     void (CPoint::*pfun)(double x_, double y_);
    这里是"指向类成员函数的指针"的声明,就是多了CPoint::的限定
     pfun = &CPoint::plus;
    这里是"指向类成员函数的指针"的赋值,在赋值的时候必须用这种静态的方式
     (pt.*pfun)(10, 10);
    这里是"指向类成员函数的指针"的使用,记住,解引用必须有实际的this指针地址,因此必须用有地址的对象pt来解引用,.*的语法有些怪异,不过我宁愿把它拆解为pt.和*pfun两部分来理解
     offset = (int&)pfun;
    这里offset=4198410,当然不同的项目,不同的编译器这个值是不同的,由此也可以知道,"指向类成员函数的指针"确实是一个指针,其实由C++对象模型我们就应该知道这个结论了
    ,在C++对象模型中,成员函数是全局的,并不属于对象
    有人想用这个值吗?或许可以用下面的代码:
     void (CPoint::*pfun2)(double x_, double y_);
     memcpy(&pfun2, &offset, sizeof(int));
     Oper(&pt, pfun2, 10, 10);
    不过,我还是忍不住奉劝各位,尽量不要直接使用这个值,这毕竟是编译器内部实现的细节,实在有太多的人喜欢这种黑客似的代码并四处炫耀,真正的"指向类成员函数的指针"
    的用法只应该包括声明,赋值和解引用

     pfun = &CPoint::move;
    注意到这里的move是虚函数,那么这里还支持虚函数的多态吗?没有问题,"指向类成员函数的指针"支持多态,当然了,代价是,这时候这个指针就必须扩展为一个结构了,C++为了
    "指向类成员函数的指针"支持多态是要付出代价的

     p3dfun = pfun; //正确
    存在基类的"指向类成员函数的指针"到派生类的"指向类成员函数的指针"的隐式转换,其含义无疑是说基类的成员函数布局信息只是派生类中成员函数布局信息的一个子集,
    因此这样的转换应该是没有问题的,但是反过来呢?
     //pfun = p3dfun; //错误
    不存在派生类的"指向类成员函数的指针"到基类的"指向类成员函数的指针"的隐式转换,因为派生类中的成员函数并不一定能够在基类中找到
    "指向类成员函数的指针"基类和派生类的关系和"指向类对象的指针"基类和派生类的关系完全相反,就"指向类成员函数的指针"的本质来说,这是合理的,但是这样的话,
    我们就无法利用公共的Oper函数了,除非...

     pfun = (void (CPoint::*)(double, double))p3dfun; //强制转换
    我们做强制转换是可以的
     Oper(&pt3d, (void (CPoint::*)(double, double))p3dfun, 10, 10);
    而且也只有强制转换才可以利用公共的Oper函数了,这里的Oper调用的是pt3d中的move函数,没有错误的
    但是是否一定要这样做呢?这取决于程序员自己的选择


     

    展开全文
  • C++指向类成员函数指针

    千次阅读 2012-12-03 23:46:58
    最近在开发中用到了函数指针,于是想整理了一下有关函数指针的概念。...而类成员函数我们也可以相似的认为,它是指向同类中同一组类型的成员函数的指针,当然这里的成员函数更准确的讲应该是指非静态的成员函

    转载于:http://blog.csdn.net/jinjinclouded/article/details/5189540

    最近在开发中用到了函数指针,于是想整理了一下有关函数指针的概念。O(∩_∩)O~

         首先 函数指针是指向一组同类型的函数的指针;而类成员函数我们也可以相似的认为,它是指向同类中同一组类型的成员函数的指针,当然这里的成员函数更准确的讲应该是指非静态的成员函数。前者是直接指向函数地址的,而后者我们从字面上也可以知道 它肯定是跟类和对象有着关系的。

         函数指针实例:

    typedef int (*p)(int,int);//定义一个接受两个int型且返回int型变量的函数指针类型
    int func(int x,int y)
    {
     printf("func:x=%d,y=%d/n",x,y);
     return (x<y?x:y);
    }

    int main()
    {
     p fun=func;//定义函数指针并给它赋上一个函数指针
     cout<<"min:"<<(*fun)(4,5)<<endl;//为什么*fun需要用()扩起来呢?因为*的运算符优先级比()低,如果不用()就成了*(fun())
     return 0;
    }

       而“指向类成员函数的指针”却多了一个类的区别:

    class A
    {
    public:
     int func(int x,int y)
     {
      printf("A::func:x=%d,y=%d/n",x,y);
      return (x<y?x:y);
     }
    };
    typedef int (A::*p)(int,int);//指针名前一定要加上所属类型类名 A::的限定

    int main()
    {
     p fun=&A::func;
     A a;                  //因为成员函数地址的解引用必须要附驻与某个对象的地址,所以我们必须创建某个对象。
     cout<<"min:"<<(a.*fun)(4,5)<<endl;
     return 0;
    }

    嘿嘿。。只是用起来 .*  感觉怪怪滴。

     

    接下来 我们可以再扩展一下下:

    #include <tchar.h>
    #include <iostream>
    #include <stdio.h>
    using namespace std;


    class A
    {
    public:
     int func1(int x,int y)
     {
      printf("A::func:x=%d,y=%d/n",x,y);
      return (x<y?x:y);
     }
     virtual int func2(int x,int y)
     {
      printf("A::func:x=%d,y=%d/n",x,y);
      return (x>y?x:y);
     }
    };
    class B:public A
    {
    public:
     virtual int func2(int x,int y)
     {
      printf("B::func:x=%d,y=%d/n",x,y);
      return (x+y);
     }

    };
    typedef int (A::*p)(int,int);//指针名前一定要加上所属类型类名 A::的限定
    typedef int (B::*p0)(int,int);

    int main()
    {
     A a;                   //因为成员函数地址的解引用必须要附驻与某个对象的地址,所以我们必须创建某个对象。
     B b;
     p fun=&A::func1;

     cout<<(a.*fun)(4,5)<<endl;
     cout<<(b.*fun)(4,5)<<endl<<endl;

     fun=&A::func2;
     cout<<(a.*fun)(4,5)<<endl;//请注意这里调用的是虚函数,嘿嘿 还真神奇 类成员函数指针也支持多态。
     cout<<(b.*fun)(4,5)<<endl<<endl;


     //fun=&B::func2;         //这样式错误滴,因为不存在派生类的"指向类成员函数的指针"到基类的"指向类成员函数的指针"的隐式转换
     fun=(int (A::*)(int,int))&B::func2;//应该进行强制转换 
     cout<<(a.*fun)(4,5)<<endl; 
     cout<<(b.*fun)(4,5)<<endl<<endl;
     
     p0 fun0=&B::func2;
     cout<<(a.*fun)(4,5)<<endl;
     cout<<(b.*fun)(4,5)<<endl<<endl;
     
     fun0=&A::func2;           //正确,因为这里进行了隐式转换
     cout<<(a.*fun)(4,5)<<endl;
     cout<<(b.*fun)(4,5)<<endl<<endl;

     //从上面我们不难发现 指向类成员函数的指针基类和派生类的关系和指向类对象的指针基类和派生类的关系完全相反,
     //基类成员函数的布局被认为是派生类成员函数布局的一个子集
     return 0;
    }

    接下  是有关模板类的类成员函数指针的使用

    实例如下:

    #include <tchar.h>
    #include <iostream>
    #include <stdio.h>
    using namespace std;


    class A
    {
    public:
     int func(int x,int y)
     {
      printf("A::func : x=%d,y=%d/n",x,y);
      return (x<y?x:y);
     }
    };
    class B
    {
    public:
     int func(int x,int y)
     {
      printf("B::func : x=%d,y=%d/n",x,y);
      return (x>y?x:y);
     }
    };

    template<class T>
    class C
    {
    public:
     T c;
     void Print()
     {
      int (T::*p)(int,int)=&T::func;
      (c.*p)(4,5);
     }
    };

    int main()
    {
     C<A> ca;
     C<B> cb;

     ca.Print();
     cb.Print();
     return 0;
    }
    从上面 可以很清晰地看到。。其实它和普通的模板没有什么区别。。只不过将限定名称该为参数名酒OK啦。。。

    嘿嘿。。。

    展开全文
  • C++类成员函数指针使用介绍

    万次阅读 多人点赞 2019-09-21 16:07:49
    在之前写过的博客中有介绍过函数指针和指针函数的区别和简单用法(文章在这里),当时的Demo非常简单,都是C语言的写法,但是当在C++中直接像C那样使用类成员函数指针时就会报错:reference to non-static member ...

    前言

    在之前写过的博客中有介绍过函数指针和指针函数的区别和简单用法(文章在这里),当时的Demo非常简单,都是C语言的写法,但是当在C++中直接像C那样使用类成员函数指针时就会报错:reference to non-static member function must be called
    所以如果是C++中的成员函数指针其使用方法是有区别的,这里针对不同的场景做个补充说明。

    类成员函数的指针(非静态)

    指向类成员函数的指针与普通函数指针的区别在于,前者需要匹配函数的参数类型和个数以及返回值类型,还要匹配该函数指针所属的类类型。

    这是因为非静态的成员函数必须被绑定到一个类的对象或者指针上,才能得到被调用对象的this指针,然后才能调用指针所指的成员函数(所有类的对象都有自己数据成员的拷贝,但是成员函数都是共用的,为了区分是谁调用了成员函数,就必须有this指针,this指针是隐式的添加到函数参数列表里去的)。

    所以,对于类成员函数的指针使用包含以下几个步骤:

    声明: 指向类的成员函数的指针需要在指针前面加上类的类型,格式为:

    typedef 返回值 (类名::*指针类型名)(参数列表);
    

    赋值: 需要用类的成员函数地址赋值,格式为:

    指针类型名  指针名 = &类名::成员函数名;
    

    注意:这里的这个&符号是比较重要的:不加&,编译器会认为是在这里调用成员函数,所以需要给出参数列表,否则会报错;加了&,才认为是要获取函数指针。这是C++专门做了区别对待。

    调用: 针对调用的对象是对象还是指针,分别用.*和->*进行调用,格式为:

    (类对象.*指针名)(参数列表);
    
    (类指针->*指针名)(参数列表);
    

    注意:这里的前面一对括号是很重要的,因为()的优先级高于成员操作符指针的优先级。

    直接来看一个示例吧:

    class Calculation
    {
    public:
        int add(int a,int b){ //非静态函数
            return  a + b;
        }
    };
    
    typedef int (Calculation::*FuncCal)(int,int);
    
    int main()
    {
        FuncCal funAdd = &Calculation::add;
        Calculation * calPtr = new Calculation;
        int ret = (calPtr->*funAdd)(1,2);  //通过指针调用
    
        Calculation cal;
        int ret2 = (cal.*funAdd)(3,4);  //通过对象调用
    
        cout << "ret = " << ret << endl;
        cout << "ret2 = " << ret2 << endl;
        return 0;
    }
    

    指向类的静态函数的指针

    类的静态成员函数和普通函数的函数指针的区别在于,他们是不依赖于具体对象的,所有实例化的对象都共享同一个静态成员,所以静态成员也没有this指针的概念。

    所以,指向类的静态成员的指针就是普通的指针。

    class Calculation
    {
    public:
        static int add(int a,int b){ //非静态函数
            return  a + b;
        }
    };
    
    typedef int (*FuncCal)(int,int);
    
    int main()
    {
        FuncCal funAdd = &Calculation::add;
        int ret = (*funAdd)(1,2);  //直接引用
        int ret2 = funAdd(3,4);  //直接引用
    
        cout << "ret = " << ret << endl;
        cout << "ret2 = " << ret2 << endl;
        return 0;
    }
    
    

    总结以上两种情况的区别:

    • 如果是类的静态成员函数,那么使用函数指针和普通函数指针没区别,使用方法一样
    • 如果是类的非静态成员函数,那么使用函数指针需要加一个类限制一下。

    使用函数指针,很多情况下是用在函数的参数中,在一些复杂的计算,如果需要重复调用,并且每次调用的函数不一样,那么这时候使用函数指针就很方便了,可以减少代码量。

    参考资料:
    https://blog.csdn.net/houzijushi/article/details/81503409
    https://www.cnblogs.com/lvchaoshun/p/7806248.html
    https://www.cnblogs.com/AnnieKim/archive/2011/12/04/2275589.html

    展开全文
  • C++ 类成员函数指针

    2014-03-02 15:12:08
    指向类成员函数指针的定义格式:  类型(类名::*指针名)(参数表) 给类成员函数指针赋值的格式:  指向函数的指针名=函数名 程序中使用指向函数的指针调用函数的格式:  (*指向函数的指针名)(实参表) #...

    指向类成员函数指针的定义格式:

            类型(类名::*指针名)(参数表)

    给类成员函数指针赋值的格式:

            指向函数的指针名=函数名

    程序中使用指向函数的指针调用函数的格式:

           (*指向函数的指针名)(实参表)

    #include<iostream>
    using namespace std;
    
    int s=0;
    
    class MyClass
    {
    	int m, n;
    public:
    	void setm(int i){m = i;}
    	void setn(int i){n = i;}
    	void disp(){cout<<"m="<<m<<endl;
    	cout<<"n= "<<n<<endl;}
    };
    
    int main()
    {
    	void (MyClass::*pfun)(int); //类成员函数指针
    	MyClass a;
    	pfun=MyClass::setm;
    	(a.*pfun)(10);
    	pfun = MyClass::setn;
    	(a.*pfun)(20);
    	a.disp();
    	return 0;
    }



    展开全文
  • 类成员函数指针和普通函数指针

    千次阅读 2019-04-19 22:07:57
    先声明一下,普通函数指针和类成员函数指针有很大的区别!所以在绑定函数的时候也会发生很多的不同的情况,本文就函数指针可能出现的各种情况一一进行分析。 测试目录: 1.普通函数指针指向普通函数 2.普通函数指向...
  • 指向 类成员函数函数指针

    千次阅读 2008-05-08 19:18:00
    原文:http://www.vckbase.com/document/viewdoc/?id=1818一、成员函数指针的用法 在C++中,成员函数的指针是个比较特殊的东西。对普通的函数指针来说,可以视为一个地址,在需要的时候可以任意转换并直接调用。但对...
  • C++ 函数指针 指向类成员函数

    千次阅读 2018-12-07 10:14:19
    //A与B的定义 class A { public:  void Test()  {  cout &lt;&lt; "A::Test()" &lt;&lt; endl;  } };   class B : public A { public:  void Test()  {  cout &lt;&...
  • 关于C++指向类成员函数指针

    千次阅读 2019-03-05 10:27:45
    疑惑:不知用处 解释: ... //类成员函数 public: void fun1() {} void fun2() {} }; int main() { void(*point1)() = fun1;//指向全局函数,ok //void(*point3)() = &amp;D::fun1;/...
  • 详解函数指针和类成员函数指针

    千次阅读 多人点赞 2017-11-12 21:35:56
    我觉得要理解这个问题,以及要理解后面的函数指针和类成员函数指针,没有什么比从计算机原理的角度来理解更容易了。这里就简要回顾一下相关知识。 众所周知,计算机(图灵机)执行程序的基本流程就是:取指令->执行...
  • 文章目录函数指针(function pointer)普通函数指针成员函数指针...相信很多人对指向一般函数的函数指针使用的比较多,而对指向类成员函数的函数指针则比较陌生。 普通函数指针 通常我们所说的 函数指针 指的是指向...
  • C++类成员函数指针2

    2012-11-17 16:54:01
    1.普通函数指针指向普通函数 2.普通函数指向非静态成员函数 3. 外部的 类函数指针 指向...4. 外部的 类函数指针 指向成员函数 5. 内部的 函数指针 指向成员函数 (类似于第2条) 6. 内部的 函数指针 指向普通函数
  • //p1是一个指向非static成员函数函数指针 void (A::*p1)(void); //p2是一个指向static成员函数函数指针 void (*p2)(void); A(){ /*对 **指向非static成员函数的指针 **和 **指向static成员函数...
  • 这里指向数据成员的指针指向成员函数指针指向变量的指针指向函数的指针进行对比来解释,比较好理解一些。指向变量的指针指向函数的指针先举个例子:void func(int a, int b){ cout ; }int main() { int ...
  • 在C++中,函数指针一般是指全局命名空间中的函数指针,类成员函数指针,与函数指针不同的是,类具有类域操作符,在声明类成员函数指针的时候,要指定成员函数返回值类型、类域操作符、成员函数参数列表
  • 今天项目中需要用到一个类似于: 接收到一个字符...一般情况下我们采用map, 如果这个函数指针指向类成员函数,可能就和一般的函数指针有点不一样了. 当然也可以采用boost 中的 bind 和 function 来实现. #
  • 由于的非静态成员函数中有一个隐形的this指针,因此,成员函数的指针和一般函数的指针的表现形式不一样。 1、指向一般函数的指针函数指针的声明中就包括了函数的参数类型、顺序和返回值,只能把相匹配的函数...
  • C++类成员函数指针

    千次阅读 2013-11-01 15:12:01
    搜到一篇不错的文章,解释比较详细,转过来。... 测试目录: 1.普通函数指针指向普通函数 2.普通函数指向非静态成员函数 ...4. 外部的 类函数指针 指向成员函数 5. 内部的 函数指针 指向成员函数
  • C++ 函数指针 & 类成员函数指针

    万次阅读 多人点赞 2013-11-21 21:17:02
    一、函数指针 函数存放在内存的代码区域内,它们同样有地址.如果我们有一个int test(int a)的函数,那么,它的地址就是函数的名字,这一点如同数组一样,数组的名字就是数组的起始地址。 1、函数指针的定义方式:...
  • c++ 全局函数指针和类成员函数指针

    千次阅读 2014-11-22 16:36:27
    c++非类成员函数指针定义 void (*pfun
  • c++类成员函数指针

    千次阅读 2021-01-19 18:04:56
    首先问大家一句,什么是函数指针? 肯定有的人会这样回答,函数指针?不就是指向函数地址的一个指针吗?或者就是一个存放着一个函数首地址的变量? 当然,那些有点底层基础的肯定会这样说,函数就是一堆连续的机器码...
  • 例如有如下,class A ...怎么声明A的成员函数指针或成员变量指针呢?int* (A::*func_ptr) (void) = &A::func; int A::*obj_ptr = &A::mem;上面声明了指向成员函数func的函数指针,和指向成员变量mem的变量指针
  • C++之指向对象成员函数指针

    千次阅读 2015-09-16 10:09:28
    1. 普通函数的指针变量定义  数据类型名 (*指针变量名)(参数列表);  例如:void (*p)( ); //p指向void型函数的指针...2. 指向对象成员函数指针变量[指向对象成员函数指针变量与普通函数的指针变量的根本区别

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 223,304
精华内容 89,321
关键字:

指向类成员函数的指针