C++ 函数指针和函数对象

  • 一、 导述
  • 二、c++成员函数在内存中的存储方式
    • 补1:静态数据和常量的区别:
  • 三、函数指针
  • 四、函数对象

一、 导述

博主认为,要想正确深入了解c++中的函数类型和函数指针,就应当首先了解在c++中成员函数在内存中的存储方式。
因此,本文会按照从基础概念到实际应用,由表及里的顺序撰写博主对函数指针和函数类型的理解。

二、c++成员函数在内存中的存储方式

c++中的内存划分为以下四个部分:

1)全局数据区(data area)
2)代码区(code area)
3)栈区(stack area)
4)堆区(heap area),即自由存储区

其中,全局数据区存放全局变量、静态数据和常量【补1】;代码区存放类成员函数和非成员函数代码;栈区存放为运行函数而分配的局部变量、函数参数、返回数据、返回地址等;余下的空间都被称为堆区。

用类去定义对象时,系统会为每个对象分配存储空间。如果一个类包含了数据和函数,要分别为数据和函数的代码分配存储空间。注意,为了节约存储空间,避免为每个对象重复开辟相同的代码区,所以在c++中,每个对象所占用的存储空间只是该对象的数据部分(虚函数指针和虚基类指针也属于数据部分)所占用的存储空间,而不包括函数代码所占用的存储空间。

因此,在类的定义时,类成员函数是放在代码区,而类的静态成员变量在类定义时就已经在全局数据区分配了内存,因而它是属于类的,对于非静态成员变量,我们是在类的实例化过程中(构造对象)为其分配内存,所以它属于对象。

另外,再补充类的静态成员函数和非静态成员函数的区别:静态成员函数和非静态成员函数都是在类的定义时存放在内存的代码区的,因此可以说他们都是属于类的,但是因为类的非静态成员函数都内含了一个指向类对象的指针型参数(即this指针),因而只有类对象才能调用(此时this指针有实际值),所以类只能调用静态成员函数,不能调用非静态成员函数(即使函数没有参数)

总结:
类的成员函数不管是不是静态的,都不占用对象的存储空间,都是存放在内存的代码区,属于类。

补1:静态数据和常量的区别:

c++有四种数据成员:
1)常量数据成员 const
2)静态数据成员static
3)普通数据成员normal
4)静态常量成员 static const

const定义的常量在超出其作用域之后,其内存空间会被释放。
const数据成员的初始化只能在类的构造函数的初始化列表中进行。要想建立在整个类中都恒定的常量,应该用类的枚举常量或者static const来实现。
const数据成员,只在某个对象生存期内是常量,而对于整个类而言却是可变的。因为类可以创建多个对象,不同的对象其const数据成员的值可以不同,所以不能在类的声明中初始化const数据成员,因为类的对象没被创建时,编译器不知道const数据成员的值是什么。

static静态成员变量不能在类的内部初始化,static定义的静态常量在函数执行后不会释放其存储空间。
static表示的是静态的。类的静态成员函数、静态成员变量是和类相关的,而不是和类的具体对象相关的。即使没有具体对象,也能调用类的静态成员函数和成员变量。一般类的静态函数几乎就是一个全局函数,只不过它的作用域限于包含它的文件。
c++中static成员不能在类的内部初始化。在类的内部只能是声明,定义必须在类定义体的外部,通常在类的实现文件中初始化。

三、函数指针

函数指针是指向函数地址的指针变量,在c++编译时,每一个函数都有一个入口地址,那么指向这个函数的函数指针便指向这个地址。
函数指针主要用于调用函数和用作函数参数。

声明方式:
typedef (*函数名)(形参)int(*Add1)(int a, int b);
int(*Add2)(int a, int b);

具体的使用方式:

int AddFunc(int a, int b)
{return a + b;
}int main()
{int(*Add1)(int a, int b);int(*Add2)(int a, int b);Add1 = AddFunc;Add2 = &AddFunc;//是否用&结果都一样,只要是将函数用作赋值,都默认转换成函数指针。cout << (*Add1)(3, 2) ;cout << (*Add2)(3, 2) << endl;return 0;
}

最后的结果是5 5

四、函数对象

c++函数对象实质上是操作符重载,实现了对()操作符的重载。c++函数对象不是函数指针,但是在程序中,它的调用方式与函数指针一样,后面加个括号就好了。

使用方式是

int AddFunc(int a, int b)
{return a + b;
}class Add{
public:const int operator()(const int a,const int b){return a + b;}
};int main()
{int(*Add1)(int a, int b);int(*Add2)(int a, int b);Add1 = AddFunc;//函数指针Add2 = &AddFunc;//函数指针cout << (*Add1)(3, 2) << endl;//函数指针cout << Add2(3, 2) << endl;//函数指针 也可以不用加*Add function;//函数对象cout << function(2, 3) << endl;return 0;
}

c++函数指针和函数对象相关推荐

  1. 【转】回调函数,函数指针与函数对象

    原文出处:http://shudingbo.spaces.live.com/blog/cns!C33400475B08F157!423.entry?wa=wsignin1.0&sa=24651 ...

  2. C++函数指针、函数对象与C++11 function对象对比分析

    1.函数指针 函数指针:是指向函数的指针变量,在C编译时,每一个函数都有一个入口地址,那么这个指向这个函数的函数指针便指向这个地址.函数指针主要由以下两方面的用途:调用函数和用作函数参数. 函数指针的 ...

  3. 函数指针 回调函数 面向对象风格的C语言

    这篇文章的所有代码都是用C实现的,这是由于C没有面向对象的特性,所以我希望用函数指针把C的结构体弄得有一点面向对象的感觉. 先介绍函数指针.回调函数,然后用C结合回调函数实现一个有面向对象风格的链表 ...

  4. c语言函数指针封装函数,C语言之函数指针、回调函数的使用

    一.背景 首先看下如下代码,这个定义是放在头文件的,在程序中tCdrvCallbackFkt也定义了另一个变量,而且括号后面还跟定义了几个变量,不理解这个定义. typedef void (PUBLI ...

  5. C语言指针数组,数组指针,函数指针,函数指针数组,函数指针数组的指针,回调函数

    C语言指针的一些知识点 指针 指针数组和数组指针的概念 函数指针,函数指针数组,函数指针数组的指针 回调函数 指针 1.指向对象的指针 int *p = new int(10); delete p; ...

  6. C++ 函数指针和函数类型

    函数指针和函数类型 函数指针指向的是函数而非对象.和其他指针类型一样,函数指针指向某种特定类型. 函数类型由它的返回值和参数类型决定,与函数名无关. bool length_compare(const ...

  7. 函数指针作为函数参数及函数作为函数参数

    转载于:http://blog.csdn.net/vlily/article/details/7244682 转载于:http://blog.csdn.net/shengnan_wu/article/ ...

  8. C++基础8【难】 回顾:数组指针,函数指针,函数指针做函数参数 C语言多态

    1,数组指针语法梳理 回顾,如何定义数组数据类型: 回顾,如何定义指针类型数组: 回顾,如何直接定义 一个指向数组类型的指针: 2,函数指针语法梳理 1)如何定义一个函数类型 2)如何定义一个函数指针 ...

  9. 函数指针和函数指针数组及其应用

    1. 函数指针 先来看一个简单的例子: int a=3; void *p=&a; 这是一个基础的不能再基础的例子.相信学过指针的都能看得懂.P是一个指针,指向a.a 是一个整形变量.函数指针和 ...

最新文章

  1. mdk编译后的HTML,[转载]keil MDK编译完成后,Program Size:
  2. 构建之法课后作业第二次作业第一题
  3. 让人失望透顶的 CSDN 博客改版
  4. PHP Notice: undefined index 解决方法
  5. CDN和智能DNS原理和应用 (原)
  6. 玩转带外触发的单目相机之一
  7. 游戏引擎cocos2d-android使用大全
  8. mysql event 变量_mysql 中event的用法
  9. 大端字节序与小端字节序的转换
  10. StarGAN v2: Diverse Image Synthesis for Multiple Domains (多域多样性图像合成)
  11. python读取python源代码文件_python 学习源码练习(2)——简单文件读取
  12. 万能电商Banner素材模板,一切产品为王
  13. 基于JAVA+SpringMVC+Mybatis+MYSQL的现代史网站设计
  14. BMC之ipmitool 命令收集
  15. java赋值语句_深度分析:面试阿里,字节99%会被问到Java类加载机制和类加载器...
  16. Day77_Flink(三)Flink时间语义和水印
  17. linux开pulseaudio服务,PulseAudio
  18. 2021莆田六中一高考成绩查询,莆田六中2018年高一新生录取名单完整版
  19. C语言文件——从创建到删除
  20. java-hiho1000A+B

热门文章

  1. 荣耀9X上手体验两个月!不吹不黑,优缺点都比较明显
  2. 工程伦理作业答案(2020.10)
  3. Wiley:International Journal for Numerical Methods in Biomedical Engineering投稿流程
  4. 专业之路:13条PS高阶技巧
  5. iText5 学习笔记
  6. 海康威视定时截图保存本地
  7. linux系统调用追踪及调试
  8. TCP/IP,单进程服务器与客户端连接通信,ipv4,TCP传输,无复用简单实例,nc模拟客户端连接服务器
  9. 算法作业——打靶问题
  10. mac删除文件(夹)报错:不能完成此操作,因为找不到一个或多个需要的项目。(错误代码 -43)