成员函数的指针

讲友元之前先讲普通的成员函数的函数指针

class Std_interface {
public:
virtual void suspend() = 0;
}; // define the pointer of function
typedef void (Std_interface::* Pstd_mem) () void f(Std_interface* p) {
Pstd_mem s = &Std_interface::suspend; // call directly
p->suspend(); // by pointer
(p->*s)();
}

当函数指针指向类成员对象时,对函数指针的定义必须加上类名以及::(作用域运算符)标识该函数指针指向哪个类的成员函数。

调用函数指针所指向的类成员函数时,必须提供函数所操作的类对象,类似于成员函数的访问,用这个对象去调用这个函数。

友元函数

那么,如果我们的函数指针已经声明成普通的函数指针,那么有无解决方案?使用友元函数,与static 函数相同的特性是:

  1. 毋须提供一个this指针去激活该函数
  2. 可以访问类的私有成员

不同之处在于该函数不处于该类的作用域之中!分析如下代码:

// GlAnimator.h
class GlAnimator {
public:
int example();
friend int LoopInThread(GlAnimator *animator_ptr);
}; // GlAnimator.cpp
typedef int(*InnerLoop)(GlAnimator *); int GlAnimator::example() {
InnerLoop inner_loop = &LoopInThread;
return 0;
}
// friend function
int LoopInThread(GlAnimator *animator_ptr) {
// ...
return 0;
}

InnerLoop inner_loop = &LoopInThread; 处是会报错的,说"LoopInThread undeclared" 这个很有意思了,明明在头文件定义了的!原因是上面提到的其作用域不在该类内,而我偏偏在成员函数example()里面去取其地址,那么显然就是没有声明的了。

解决方案就是重新声明一遍,一共声明两遍,在取函数指针前声明即可,我喜欢在头文件里做,头文件修改如下:

// GlAnimator.h
class GlAnimator {
public:
int example();
friend int LoopInThread(GlAnimator *animator_ptr);
}; // declare the friend function again
int LoopInThread(GlAnimator *animator_ptr);

参考资料

http://www.cplusplus.com/forum/general/23265/

http://hipercomer.blog.51cto.com/4415661/941682

C++ 友元函数的函数指针的更多相关文章

  1. C++ 类 & 对象-C++ 内联函数-C++ this 指针-C++ 类的静态成员

    C++ 内联函数 C++ 内联函数是通常与类一起使用.如果一个函数是内联的,那么在编译时,编译器会把该函数的代码副本放置在每个调用该函数的地方. 对内联函数进行任何修改,都需要重新编译函数的所有客户端 ...

  2. C++虚函数和函数指针一起使用

    C++虚函数和函数指针一起使用,写起来有点麻烦. 下面贴出一份示例代码,可作参考.(需要支持C++11编译) #include <stdio.h> #include <list> ...

  3. 12-返回指针的函数&&指向函数的指针

    前言 接下来我只讲指针的最常见用法,比如这一章的内容----返回指针的函数 与 指向函数的指针   一.返回指针的函数 指针也是C语言中的一种数据类型,因此一个函数的返回值肯定可以是指针类型的. 返回 ...

  4. C++:成员运算符重载函数和友元运算符重载函数的比较

    5.2.4 成员运算符重载函数和友元运算符重载函数的比较 (1)对双目运算符而言,成员运算符重载函数参数表中含有一个参数,而友元运算符重载函数参数表中有两个参数:对于单目运算符而言,成员运算符重载函数 ...

  5. C ~ 指针函数与函数指针的区别

    一. 在学习arm过程中发现这“指针函数”与“函数指针”容易搞错,所以今天,我自己想一次把它搞清楚,找了一些资料,首先它们之间的定义: 1.指针函数是指带指针的函数,即本质是一个函数.函数返回类型是某 ...

  6. c语言指针函数与函数指针

    例一:指针函数 指针函数是指带指针的函数,即本质是一个函数.函数返回类型是某一类型的指针 类型标识符    *函数名(参数表) int *f(x,y); 首先它是一个函数,只不过这个函数的返回值是一个 ...

  7. C++中怎么获取类的成员函数的函数指针?

    用一个实际代码来说明. class A { public: staticvoid staticmember(){cout<<"static"<<endl;} ...

  8. typedef 用法及 指针函数 和 函数指针

    typedef 本质上是定义了一种新的类型, 该新类型可以原有类型的别名或是原有类型的组合. 而#define 只是字符串的替换. 如定义: typedef char* CHARP; 则 CHARP ...

  9. thiscall仅仅应用于“C++”成员函数(this指针存放于CX寄存器,参数从右到左压)

    _stdcall是Pascal程序的缺省调用方式,通常用于Win32 Api中,函数采用从右到左的压栈方式,自己在退出时清空堆栈.VC将函数编译后会在函数名前面加上下划线前缀,在函数名后加上" ...

随机推荐

  1. bzoj3571————2016——3——12(最小乘积匹配)

    bzoj3571 传送门http://www.lydsy.com/JudgeOnline/problem.php?id=3571 题解: ——————来自伟大的thy大神  http://blog.c ...

  2. C# 存储过程使用方法

                CREATE PROCEDURE [dbo].[GetNameById] @studentid varchar(8), @studentname nvarchar(50) OU ...

  3. Linux 线程调度与优先级设置

    转载:http://blog.csdn.net/a_ran/article/details/43759729 线程调度间的上下文切换 什么是上下文切换? 如果主线程是唯一的线程,那么他基本上不会被调度 ...

  4. js 验证文本框只能输入数字和小数点

    第一步.添加js方法 function check(e) {     var re = /^\d+(?=\.{0,1}\d+$|$)/     if (e.value != "") ...

  5. Selenium2(java)selenium常用API 五

    上传文件   元素标签是input时上传方式 上传是一个input,对于这种元素是input 的标签可以采用元素的sendKeys()方法来直接赋值,upload.html代码: <html&g ...

  6. Scrum

    Scrum[编辑] 维基百科,自由的百科全书   Scrum是一种敏捷软件开发的方法学,用于迭代式增量软件开发过程.Scrum在英语是橄榄球运动中争球的意思. 虽然Scrum是为管理软件开发项目而开发 ...

  7. Cocos2d-x 多分辨率适配完全解析

    从Cocos2d-x 2.0.4开始,Cocos2d-x提出了自己的多分辨率支持方案,废弃了之前的retina相关设置接口,提出了design resolution概念. 有以下相关接口: CCEGL ...

  8. HoloLens开发手记 - 构建2D应用 Building 2D apps

    HoloLens可以让我们在真实世界中看到全息图像内容.但是它本质上还是一台Windows 10设备,这意味着HoloLens可以以2D应用形式运行Windows Store里的大部分UWP应用. 目 ...

  9. Java中的==、equals、hasCode方法

    == java 的数据类型分为“基本数据类型” 和“引用数据类型”在基本数据类型的比较中,== 比的就是基本数据类型变量中所保存的值在引用数据类型的比较中,== 才比较的是变量所指向的对象的地址. e ...

  10. 在C++中反射调用.NET(二)

    反射调用返回复杂对象的.NET方法 定义数据接口 上一篇在C++中反射调用.NET(一)中,我们简单的介绍了如何使用C++/CLI并且初步使用了反射调用.NET程序集的简单方法,今天我们看看如何在C+ ...