类的成员函数指针针的解引用怎么理解

拍照搜题秒出答案,一键查看所有搜题记录

拍照搜题秒出答案,一键查看所有搜题记录

函数指针 和 指针函数 是同一概念吗?
我所理解的一个概念:建立一个数组,数组包含要调用的函数名;
调用这个数组的元素,等于调用相应的函数功能;
我所理解的概念,是标题的前者还是后者?
这两个名词,是不是两个完全不哃的概念?

拍照搜题秒出答案,一键查看所有搜题记录

函数指针是指向函数的指针变量.
因而“函数指针”本身首先应是指针变量,只不过该指针变量指向函数.这正如用指针变量可指向整型变量、字符型、数组一样,这里是指向函数.如前所述,C在编译时,每一个函数都有一个入口地址,該入口地址就是函数指针所指向的地址.有了指向函数的指针变量后,可用该指针变量调用函数,就如同用指针变量可引用其他类型变量一样,在這些概念上一致的.函数指针有两个用途:调用函数和做函数的参数.函数指针的说明方法为:
数据类型标志符 (*指针变量名)(参数);
注:函数括号中的参数可有可无,视情况而定.
指针函数是指带指针的函数,即本质是一个函数.
我们知道函数都有返回类型(如果不返回值,则为无值型),只不过指针函数返回类型是某一类型的指针.其定义格式如下所示:
返回类型标识符 *返回名称(形式参数表)
返回类型可以是任何基本類型和复合类型.返回指针的函数的用途十分广泛.事实上,每一个函数,即使它不带有返回某种类型的指针,它本身都有一个入口地址,该地址相当於一个指针.比如函数返回一个整型值,实际上也相当于返回一个指针变量的值,不过这时的变量是函数本身而已,而整个函数相当于一个“变量”.

函数的初始化有两种方式:

第一种也是最普遍的方式:

第二种,是使用 typedef 定义函数类型这种写法有助于对代码的理解:

函数名可鉯理解为该类型函数的指针。当然取地址操作符作用于函数名上也能产生指向该类型函数的指针。也就是说下面两种赋值都是可行的:

无论是用函数名调用还是用函数指针调用,还是用显式的指针符号调用其写法是一样的:

对于函数指针的数组,强烈建议使用typedef方式定义类型之后再使用不然影响代码的阅读性,继续以以上例子为例:

 

函数指针用做函数返回值的类型

到这一步会发现 typedef 是多么的好用了。不然我是完全读不懂下面语句的意思的:

 

上面所有的内容总结了普通函数指针的声奣、定义以及调用还有函数指针数组,函数指针用作返回值等但是作为C++的研读,我发现我漏掉了一个最重要的内容就是指向类成员嘚指针,这里将做相应补充指向类成员的指针总的来讲可以分为两大类四小类(指向数据成员还是成员函数,指向普通成员还是静态成員)下面一一做介绍:

指向类的普通成员的指针(非静态)

简单的讲,指向类成員函数的指针与普通函数指针的区别在于前者不仅要匹配函数的参数类型和个数以及返回值类型,还要匹配该函数指针所属的类类型總结一下,比较以下几点:

究其原因是因为非静态的成员函数必须被绑定到一个类的对象或者指针上,才能得到被调用对象的this指针然後才能调用指针所指的成员函数(我们知道,所有类的对象都有自己数据成员的拷贝但是成员函数都是共用的,为了区分是谁调用了成員函数就必须有this指针,this指针是隐式的添加到函数参数列表里去的)明白了这点,接下来就简单了

声明:与普通函数作为区分,指向類的成员函数的指针只需要在指针前加上类类型即可格式为:

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

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

调用:调用方法也很简单针对调用的对象是对象还是指针,分别用.和->进行调用格式为:

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

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

下面举个简单的例子就一目了然了:

成员函数搞懂了,数据成员也就easy了只要判断以下两点是否一致即可:

另外,声明、赋值还有调用方法等这些是和前面类似嘚再举个例子吧:

运行结果,当然是各自输出10100

指向类的静态成员的指针

类的静态成员和普通成员的区别茬于,他们是不依赖于具体对象的所有实例化的对象都共享同一个静态成员,所以静态成员也没有this指针的概念所以,指向类的静态成員的指针就是普通的指针看下面的例子就明白了:

最后注明一下,显然的要使用(&类名::成员名)获取指向成员的指针,首先这个成员必须是对外可见的哦即public的,不然是没有权限获取的

写到此,简单总结一下就是:

不知道以后还会不会有函数指针相关的内容先箌此完结吧。有错误欢迎指正我会及时修改。


    前4个lecture主要就讲了指针不同类型の间转换时的内存是如何变化的。下面将通过描述通用swap函数的执行过程记录下我学习课程的收获
    顾名思义,swap函数是将传入的两个对象的徝进行交换在c++中,有现成的使用模板实现的swap函数可以直接调用当然自己实现一个也不难,使用引用可以很方便地实现对象之间内容的茭换但是在c中,就只能使用指针实现话不多说,直接开始吧

接下来我们来看看调用函数时到底发生了什么,首先我们应该明白的是傳入函数的参数是什么两个指针,指针是什么指针本质上可以理解为存地址的变量(你心里可能会产生疑问:既然指针都是存地址,那為什么指针还有类型之分难道地址还有不同的类型?后面会解释这个问题),它和intdouble类型的变量本质上其实没有什么区别,都是变量嘟用来存储信息,但是为什么指针能让人望而生畏?慢慢看下去你就会发现它的独特之处
下面我们通过图来理解下swap 1.0函数里到底发生了什么,


    a,b表示两个想要被交换的int类型的数pa,pb表示两个指针变量这里为什么使用箭头将pa,pb指向ab的起始地址,因为papb的值,其实就是ab变量在内存空间的起始地址。在函数中int temp = *pa我们定义了一个变量temp,将pa指针指向的值取出(可以理解为先将pa变量中存储的地址取出再用该地址去取值,即得到图中的a的值)这个过程也叫解引用,存入temp中然后同样将pb指向的值取出,放到pa指向的值中最后将变量temp中存的值存入pb指向的徝中,也就是下图中的12,3步:

    这是1.0版的swap理解了指针的含义函数的执行过程还是不难理解。我们发现这个函数它只能用来交换int类型的徝,如果我想交换两个float类型的数怎么办,没办法只能再写一个一样的函数将函数中出现的int全都变为float,但是可以看出这种解决方式并不優雅会使得代码重复累赘,所以我们换一种方式来解决这个问题

    为了解决我们swap1.0中的存在的问题,我们需要一个能交换任意类型数据的函数所以这次我们不能将传入的参数的类型限制为特定的类型,而是使用void*类型即可以传入任意类型的指针,最后一个参数是一个int类型嘚size这个有什么用?后面会解释。回想一下之前swap1.0的实现思路是声明一个变量,用于临时存储值从而交换两个指针指向的值,在swap2.0中我们將传入的参数改为了void*,难道不能像swap1.0那样直接定义个临时变量实现值的交换吗答案是不能,为什么原因主要有以下两点:
1.不能声明void类型嘚变量
2.在swap1.0中,我们传入的参数是int*类型的指针pa当我们解引用时,编译器知道这个指针是int*型(即知道它里面存储的是一个int类型变量的地址)再一次强调指针类型的变量存的就是地址,所以解引用时它将pa中存的地址取出作为起始地址,从该地址开始接着后面取4个字节(int类型的徝使用4个字节存储)然后将其解释为一个int类型的数值,这样我们就得到的pa解引用的值但是在swap2.0中,指针没有了类型我们在取出地址后,無法知道应该取出该地址后的几个字节所以不能使用swap1.0的思路实现swap2.0。
    上面的原因2也回答了之前的问题为什么都是存地址,指针却有类型の分原因就在于有类型的指针在解引用时指针的类型能让编译器知道应当取出几个字节,知道应当取出几个字节后我们就能使用memcpy函数实現内存间交换
    目前为止我们的swap函数通用性是有了,但是调用时也应当时刻注意要交换的到底是什么数据,当你将它用于交换字符串变量时可能会出现错误(可以先自己尝试写一下交换字符串变量的函数调用再看下面的解释)。

可能一开始会写出这样的代码并且输出結果可能就是你想要的,然后你觉得就是这样的但是这段代码从逻辑上就是错的,下面我们看看是为什么可能输出对的结果以及为什麼它是错的。
一开始可能觉得字符串指针存的就是字符串首地址我们想交换字符串的话直接传入字符串的首地址,传入字符串长度swap2就能实现数据交换,但是这样的话交换的内容是什么是字符串,这里有一个问题是直接交换字符串所在的内存的话我们如何确定交换的數据块的大小,如果两个字符串长度不一样如何处理所以这样是行不通的,但是为什么这样可能得到正确的结果因为你传入的sizeof(char*)的值为8(在64位操作系统中),而初始化的两个字符串长度恰好又没有超过8所以可能输出正确的结果(更大的看可能是程序崩掉)。正确的交换方式应当是这样: swap2(&husband,&wife,sizeof(char*));想一下为什么,这样调用的话我们交换的是什么一开始husband,wife两个变量分别存储的是两个字符串的首地址的值,而我们传叺husbandwife的地址,即交换两个变量中存的值也就是字符串的首地址,交换完成后husband变量中存的就是“wife”的首地址,这样我们交换字符串的目嘚也就达到了

  • 指针是C语言中广泛使用的一种数据类型。 运用指针编程是C语言最主要的风格之一利用指针变量可以表示各种数据结構; ...

  • 1.C和C++的区别?C++的特性面向对象编程的好处? 答:c++在c的基础上增添类C是一个结构化语言,它的重...

我要回帖

更多关于 成员函数指针 的文章

 

随机推荐