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()函数。
C/C++编程笔记:C++中的 const 成员函数
像成员函数和成员函数参数一样,类的对象也可以声明为const。声明为const的对象无法修改,因此只能调用const成员函数,因为这些函数确保不修改该对象。
可以通过在对象声明的前缀const关键字来创建const对象。任何试图更改const对象的数据成员的尝试都会导致编译时错误。
句法:
const Class_Name Object_name;
当函数声明为const时,可以在任何类型的对象,const对象以及非const对象上调用它。
每当将对象声明为const时,都需要在声明时对其进行初始化。但是,只有在构造函数的帮助下,才可以在声明时进行对象初始化。
当在函数的声明中使用const关键字时,该函数将变为const。const函数的想法是不允许它们修改调用它们的对象。建议实践中使尽可能多的函数常量化,以便避免意外更改对象。
以下是const函数的简单示例:
输出:20
当函数声明为const时,可以在任何类型的对象上调用它。非常量函数只能由非常量对象调用。
例如,以下程序有编译器错误:
输出: passing \’const Test\’ as \’this\’ argument of \’int
Test::getValue()\’ discards qualifiers
让我们看另一个例子:
输出:Hello world I\’m Rancho Baba Inside display() Function
以上。
每天学点小知识,希望对你有帮助~
另外如果你想更好地提升你的编程能力,学好C语言C++编程!弯道超车,快人一步!笔者这里或许可以帮到你~
编程学习书籍分享:
编程学习视频分享:
分享(源码、项目实战视频、项目笔记,基础入门教程)
欢迎转行和学习编程的伙伴,利用更多的资料学习成长比自己琢磨更快哦!
本文作者及来源:Renderbus瑞云渲染农场https://www.renderbus.com
文章为作者独立观点不代本网立场,未经允许不得转载。