类成员函数指针区别于用法

简介: 通常的函数指针大家已经非常熟悉了。但我们今天讨论一下类成员函数指针的用法。 今天我们来看一下成员函数指针,加入我们想要声明一个 void CTest::Show()成员函数指针类型,那么我们一般的做法是: typedef void(CTest::*pShow)(); 从上面可以看出一些和一般函数指针类型不同的地方。

通常的函数指针大家已经非常熟悉了。但我们今天讨论一下类成员函数指针的用法。

今天我们来看一下成员函数指针,加入我们想要声明一个 void CTest::Show()成员函数指针类型,那么我们一般的做法是:

typedef void(CTest::*pShow)();

从上面可以看出一些和一般函数指针类型不同的地方。让我们把他和一般的函数声明比较一下。下面是一般的函数声明:

typedef void(*pShow)();

我们可以看出成员函数指针和一般函数指针的不同,那就是成员函数指针声明时加上类限制。这会起到什么作用呢?和类成员函数一样,那就是编译器会在编译的时候在函数指针对应的函数调用中加上this指针。所以类成员函数不能单独调用,一定要注意。必须与类对象配合调用。

 

下面是一个简单的成员函数指针类型的使用例子:

#include "stdafx.h"
#include <iostream>

using namespace std;
class Test

{

 int sum;

public:

 Test():sum(0){}

 int Add(int a,int b) {return (sum = a + b);}

 void Show() {cout<<"Show()";}

};

 

 

//////////////////////////////////////////////////////////cpp//////////////////////////////////////////////////////////////////////////

 

 

typedef void(Test::*pShow)();
typedef int(Test::*pAdd)(int,int);


int _tmain(int argc, _TCHAR* argv[])

{

 Test t;

 pShow Show=&Test::Show;
 pAdd  Add=&Test::Add;


 (t.*Show)();
 cout<<(t.*Add)(2,5);

}

结果:Show()7

注意其中特别的语法:

1:给指针变量赋值时,要在用来赋值的成员函数名前面加'&'符号。

2:注意(t.*Add)(2,5)可不能能写成t.*Add(2,5);因为括号的优先级比*高。所以要写成(t.*Add)(2,5)或者(t.Add)(2,5)。后者之所以可以,因为函数名本身可以当地址,但C++同时也支持&函数名为取函数地址。这关系到如果看待函数名以处理函数指针的重要问题。

 

既然说到成员函数指针的那么,我们很可能会想到它是否具有向类的函数一样的特殊性质,特别是虚函数?是的,成员函数指针就有虚函数的特性。看下例:

#include "stdafx.h"
#include <iostream>

using namespace std;
class A
{
public:
 virtual void Show() {cout<<"A";}
};

class B:public A
{
public :
 void Show() {cout<<"B";}
};

 

//////////////////////////////////////////////////////////cpp//////////////////////////////////////////////////////////////////////////

 

 

typedef void(A::*pShow)();


int _tmain(int argc, _TCHAR* argv[])

{

 B t;

 pShow Show=(pShow)&A::Show;
 pShow Show=(pShow)&B::Show;

 (t.Show)();
 cin.get();

}

结果:BB

 

通过结果可以看出,虽然声明的基类的虚函数指针,但是函数指针调用时还是根据调用对象来相应的函数,颇像虚函数。所以基类成员函数指针可以根据运行时对象的类型来确定的对应的函数调用。

 

但其中有一个容易忽略的语法:

基类指针=派生类函数地址,这种隐式赋值是不行。也就是说

pShow Show=&B::Show;

编译时不通过的,也就是说C++认为将派生类成员函数名赋给基类成员函数指针是可能存在问题的。可能你会想,我们经常将派生类对象给基类指针啊,

是啊,不过两者不是一回事,考虑的角度不同。

 

前者的解释:基类的函数布局(个数)是派生类的函数布局的子集。所以基类的函数赋给派生类的函数指针时,因为派生类肯定有(public的基类函数)此函数,所以赋值很安全。反过来,你想有可能会出现问题。

后者的解释:基类所做的操作涉及的数据成员不会超出派生类的范围。所以把派生类对象给基类指针,基类来处理没问题。也很安全。反过来呢,你也知道,很危险滴!

 

所以在使用成员函数指针时大家还需多多注意。

相关文章
|
5天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
18 4
|
21天前
|
存储 安全 编译器
在 C++中,引用和指针的区别
在C++中,引用和指针都是用于间接访问对象的工具,但它们有显著区别。引用是对象的别名,必须在定义时初始化且不可重新绑定;指针是一个变量,可以指向不同对象,也可为空。引用更安全,指针更灵活。
|
28天前
|
存储 C语言
C语言指针与指针变量的区别指针
指针是C语言中的重要概念,用于存储内存地址。指针变量是一种特殊的变量,用于存放其他变量的内存地址,通过指针可以间接访问和修改该变量的值。指针与指针变量的主要区别在于:指针是一个泛指的概念,而指针变量是具体的实现形式。
|
1月前
|
存储 编译器 C语言
C++入门2——类与对象1(类的定义和this指针)
C++入门2——类与对象1(类的定义和this指针)
28 2
|
3月前
|
编译器 C++
virtual类的使用方法问题之在C++中获取对象的vptr(虚拟表指针)如何解决
virtual类的使用方法问题之在C++中获取对象的vptr(虚拟表指针)如何解决
|
4月前
|
存储
头指针和头结点的区别
头指针和头结点的区别
147 1
|
5月前
|
Java
2022蓝桥杯大赛软件类国赛Java大学B组 左移右移 空间换时间+双指针
2022蓝桥杯大赛软件类国赛Java大学B组 左移右移 空间换时间+双指针
42 3
|
5月前
|
存储 Java C#
C++语言模板类对原生指针的封装与模拟
C++|智能指针的智能性和指针性:模板类对原生指针的封装与模拟
|
5月前
|
C++
C++职工管理系统(类继承、文件、指针操作、中文乱码解决)
C++职工管理系统(类继承、文件、指针操作、中文乱码解决)
C++职工管理系统(类继承、文件、指针操作、中文乱码解决)
|
5月前
|
存储 C语言
一级指针和二级指针的区别
一级指针和二级指针的区别
67 1