百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术流 > 正文

C++类成员函数,如何定义函数指针?归纳、总结 linux C++第39讲

citgpt 2024-07-10 14:45 10 浏览 0 评论

1.2.2 指向对象成员函数的指针

对象的成员函数是一个函数,那么,我们可以定义一个函数指针,指向对象的成员函数。但是,该函数指针变量的定义,与普通的函数指针变量定义不同。

首先,我们先看看指向“普通函数”的指针变量的定义方法:

C++类成员函数,如何定义函数指针?归纳、总结 linux C++第39讲

数据类型名 (* 指针变量名)(参数列表);

例如:

void (*pf)(int); //定义函数指针pf,指向的函数是带有1个int类型的参数,并且,返回类型是void

所以,它可以指向一个函数,并通过函数指针调用该函数,如下:

pf = func; //将func()函数的入口地址赋给指针变量pf,所以,pf就指向func()函数

(*pf)(); //调用func()函数

而定义一个指向“对象成员函数”的指针变量则比较复杂一些,如果模仿普通函数指针的定义,定义一个函数指针,指向student类的print()函数,如下:

void (*pf)();

然后,将对象成员函数名赋给指针变量pf:

student stud("wkf","xxxmylinux.vip",xxx6572996); //定义对象

pf = stud.print;

此时,编译错误,为什么呢?成员函数与普通函数有最根本的区别:它是类中的一个成员。编译系统要求在上面的赋值语句中,指针变量的类型必须与赋值右侧函数的类型匹配,要求以下3个方面都要匹配:

(1) 函数参数的类型和参数的个数。

(2) 函数返回值类型。

(3) 函数所属的类。

在这3点中1和2这两点都匹配了,但是,第三点不匹配。指针变量pf与类无关,而print()函数却属于student类。因此,要区别普通函数和成员函数的不同性质,不能在类外直接用成员函数名作为函数入口地址去调用成员函数。

那么,应该怎么样定义指向成员函数的指针变量呢?应该采用下面的形式:

void (student::*pf)(); //定义函数指针pf ,指向student类中共有成员的函数,其返回类型是void,而且无参数

注意:(student::*pf) 两侧的括号不能省略,因为()的优先级高于*,如果无此括号,就相当于:

void student:: *(pf()); //这是返回值为void 类型指针的函数

定义指向公用成员函数的指针变量的一般形式为:

数据类型名(类名::*指针变量名)(参数列表);

可以让它指向一个公用成员函数,只需把公用成员函数的入口地址赋给一个指向公用成员函数的指针变量即可,如:

pf = &student::print;

使指针变量指向一个公用成员函数的一般形式为:

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

这样,定义的函数指针变量,指向了一个类中的一个函数。但是,当一个类实例化为多个对象的时候,到底要怎么样使用该函数指针?函数指针是指向了哪一个对象的函数。所以,我们在调用函数指针的时候,就必须指定哪一个对象。下面的测试例子说明了该问题。

在VC++系统中,也可以不写“&”取地址符,与C语言的用法一样。但是,建议在写C++程序的时候,不应省略“&”运算符。


可以看到,我们定义pfunc函数指针。它是student类中的一个函数,这个函数的类型是:

(1) 返回值是void类型;

(2) 函数参数空;

然后,在main()函数中给pfunc函数指针赋值,让它指向student::print()函数。

注意,成员函数的入口地址的正确写法是:&类名::成员函数名,如下:

pfunc = &student::print;

而不应该写成:

pfunc = &stud::print;

因为,对象的成员函数不是存放在对象的空间中的,而是存放在对象外的空间中。如果有多个同类的对象,它们公用同一个函数代码段,类定义的成员函数,不是属于某一个对象,而是属于该类,由所有的类对象共享。因此,student类中的print()成员函数,不是属于stud对象,而是属于student类。所以,给指针变量 pfunc赋值的地址,应该是student类公用的函数代码段的入口地址。

所以,使用“类名::函数名”来指定函数,那么,我们在调用函数指针所指向的函数时,应该明确指出是“哪一个对象”,所以,在调用的时候,如下:

(对象名.*函数指针名)();

其中,对象名就指定了调用该函数指针指向的哪一个对象中的函数。例如,上面的例子,给函数指针pfunc设置的是student类的print()函数。

那么,要调用执行函数指针pfunc,需要让函数指针pfunc实例化,指向某一个具体的对象。相当于某一个student类对象调用函数指针pfunc所指向的函数。所以,调用如下:

(stud.* pfunc)();

此时,就是调用stud对象中函数指针pfunc所指向的print()函数,相当于执行stud.print()函数。

相关推荐

js中arguments详解

一、简介了解arguments这个对象之前先来认识一下javascript的一些功能:其实Javascript并没有重载函数的功能,但是Arguments对象能够模拟重载。Javascrip中每个函数...

firewall-cmd 常用命令

目录firewalldzone说明firewallzone内容说明firewall-cmd常用参数firewall-cmd常用命令常用命令 回到顶部firewalldzone...

epel-release 是什么

EPEL-release(ExtraPackagesforEnterpriseLinux)是一个软件仓库,它为企业级Linux发行版(如CentOS、RHEL等)提供额外的软件包。以下是关于E...

FullGC详解  什么是 JVM 的 GC
FullGC详解 什么是 JVM 的 GC

前言:背景:一、什么是JVM的GC?JVM(JavaVirtualMachine)。JVM是Java程序的虚拟机,是一种实现Java语言的解...

2024-10-26 08:50 citgpt

使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
  • 使用Spire.Doc组件利用模板导出Word文档
跨域(CrossOrigin)

1.介绍  1)跨域问题:跨域问题是在网络中,当一个网络的运行脚本(通常时JavaScript)试图访问另一个网络的资源时,如果这两个网络的端口、协议和域名不一致时就会出现跨域问题。    通俗讲...

微服务架构和分布式架构的区别

1、含义不同微服务架构:微服务架构风格是一种将一个单一应用程序开发为一组小型服务的方法,每个服务运行在自己的进程中,服务间通信采用轻量级通信机制(通常用HTTP资源API)。这些服务围绕业务能力构建并...

深入理解与应用CSS clip-path 属性
深入理解与应用CSS clip-path 属性

clip-pathclip-path是什么clip-path 是一个CSS属性,允许开发者创建一个剪切区域,从而决定元素的哪些部分可见,哪些部分会被隐...

2024-10-25 11:51 citgpt

HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
  • HCNP Routing&Switching之OSPF LSA类型(二)
Redis和Memcached的区别详解
  • Redis和Memcached的区别详解
  • Redis和Memcached的区别详解
  • Redis和Memcached的区别详解
  • Redis和Memcached的区别详解
Request.ServerVariables 大全

Request.ServerVariables("Url")返回服务器地址Request.ServerVariables("Path_Info")客户端提供的路...

python操作Kafka

目录一、python操作kafka1.python使用kafka生产者2.python使用kafka消费者3.使用docker中的kafka二、python操作kafka细...

Runtime.getRuntime().exec详解

Runtime.getRuntime().exec详解概述Runtime.getRuntime().exec用于调用外部可执行程序或系统命令,并重定向外部程序的标准输入、标准输出和标准错误到缓冲池。...

promise.all详解 promise.all是干什么的
promise.all详解 promise.all是干什么的

promise.all详解promise.all中所有的请求成功了,走.then(),在.then()中能得到一个数组,数组中是每个请求resolve抛出的结果...

2024-10-24 16:21 citgpt

Content-Length和Transfer-Encoding详解
  • Content-Length和Transfer-Encoding详解
  • Content-Length和Transfer-Encoding详解
  • Content-Length和Transfer-Encoding详解
  • Content-Length和Transfer-Encoding详解

取消回复欢迎 发表评论: