类成员函数指针的特殊之处(成员函数指针不是指针,内含一个结构体,需要存储更多的信息才能知道自己是否virtual函数)
下面讨论的都是类的非静态成员函数。
类成员函数指针的声明及调用:
|
1
2
3
4
5
6
7
|
//pr是指向Base类里的非静态成员函数的指针//其行参为(int, int),返回值为voidvoid (Base::*pr)(int, int);//需通过对象调用//object是Base类的一个对象或指针(可多态)( object->*pr)( _r, _c) |
而其实质和普通的指针也有区别:
//下面是隐藏的代码是相关类型的定义
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
void Foo1(int a, int b, int c){ return;}void Foo2(int a, int b){ return;}class Base{public: void Foo3(int a, int b, int c) {return;} void Foo3(int a,int b) {return;}}; |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
#include<iostream>using namespace std;int main(){ void (Base::*p1)(int,int,int) = &(Base::Foo3); void (Base::*p2)(int,int) = &(Base::Foo3); void (Base::*p3)(int,int,int) = NULL; cout<<"Foo1: "<<Foo1<<'\t'<<sizeof(&Foo1)<<'\n' <<"Foo2: "<<Foo2<<'\t'<<sizeof(&Foo2)<<'\n' <<"p1: "<<p1<<'\t'<<sizeof(p1) <<'\n' <<"p2: "<<p2<<'\t'<<sizeof(p2) <<'\n' <<"p3: "<<p2<<'\t'<<sizeof(p3) <<endl;} |
输出结果为:
Foo1: 00BB1510 4
Foo2: 00BB1520 4
p1: 1 4
p2: 1 4
p3: 0 4
从结果上来看,指向成员函数的指针值均为1。且在调试过程中可以看到:
p1 error: cannot obtain value void*
p2 error: cannot obtain value void*
p3 error: cannot obtain value void*
但这个指针指向的函数实际上是可以被调用的。
搜索之,看到了一篇文章:
http://blog.csdn.net/hairetz/archive/2009/05/06/4153252.aspx
1。成员函数指针不是指针。从代码看出,在main函数的调用栈(calling stack)中首先依次压入四个成员函数指针,如果它们是普通指针的话,它们之间的偏移量应该是4个字节,可是实际的情况却是这样的:
”The implementation of the pointer to member function must store within itself information as to whether the member function to which it refers is virtual or nonvirtual, information about where to find the appropriate virtual function table pointer (see The Compiler Puts Stuff in Classes [11, 37]), an offset to be added to or subtracted from the function's this pointer (see Meaning of Pointer Comparison [28, 97]), and possibly other information. A pointer to member function is commonly implemented as a small structure that contains this information, although many other implementations are also in use. Dereferencing and calling a pointer to member function usually involves examining the stored information and conditionally executing the appropriate virtual or nonvirtual function calling sequence.“
这篇文章较深入地研究了成员函数指针,及比较了普通成员函数指针和虚函数指针在转化的过程中存在那些差异。
类成员函数指针的特殊之处(成员函数指针不是指针,内含一个结构体,需要存储更多的信息才能知道自己是否virtual函数)的更多相关文章
- NX二次开发-如何在类外面定义一个结构体
#include <uf.h> #include <uf_obj.h> #include <uf_part.h> using namespace NXOpen; u ...
- (C/C++) 用函数返回一个结构体
方法一: 参数里含有指向指针的指针. 注意:如果函数参数里只有一个指向结构体的指针,是无法正确地返回结构体的值的.原因在于在编译的时候,会对入参p产生一个备份_p. 参考此文:http://www.c ...
- QMap的key也可以是一个结构体类吗?
QMap<usbsnvidpid, QVector<QString>> USBVIDPIDTIME; USBVIDPIDTIME.insert(m_vidpidsn, time ...
- 由结构体成员地址计算结构体地址——list_entry()原理详解
#define list_entry(ptr, type, member) container_of(ptr, type, member) 在进行编程的时候,我们经常在知道结构体地址的情况下,寻找其中 ...
- OC对象里面包含的结构体类型的属性,不能对该结构体属性的成员单个进行修改
OC对象里面包含的结构体类型的属性,不能对该结构体属性的成员单个进行修改,需要对OC对象的结构体属性整体赋值. 关于网上很多博客写着“结构体类型里面的某个属性如果想要修改是不允许单个修改的” 之解释: ...
- 深入理解指针—>结构体里的成员数组和指针
单看这文章的标题,你可能会觉得好像没什么意思.你先别下这个结论,相信这篇文章会对你理解C语言有帮助.这篇文章产生的背景是在微博上,看到@Laruence同学出了一个关于C语言的题,微博链接.微博截图如 ...
- 读陈浩的《C语言结构体里的成员数组和指针》总结,零长度数组
原文链接:C语言结构体里的成员数组和指针 复制例如以下: 单看这文章的标题,你可能会认为好像没什么意思.你先别下这个结论,相信这篇文章会对你理解C语言有帮助.这篇文章产生的背景是在微博上,看到@Lar ...
- 全面总结sizeof的用法(定义、语法、指针变量、数组、结构体、类、联合体、位域位段)
一.前言 编译环境是vs2010(32位). <span style="font-size:18px;">#include<iostream> #inclu ...
- C++,关于类和结构体中,成员访问属性(public,private)
今天发现一个的问题: #include <vector> #include <iostream> #include <algorithm> #include < ...
随机推荐
- Springboot系列:@SpringBootApplication注解
在使用 Springboot 框架进行开发的时候,通常我们会在 main 函数上添加 @SpringBootApplication 注解,今天为大家解析一下 @SpringBootApplicatio ...
- 设计模式在JDK中的应用
在JDK(Java Development Kit)类库中,开发人员使用了大量设计模式. 创建型模式: (1) 抽象工厂模式(Abstract Factory) • java.util.Calenda ...
- 聊聊PROFINET与PROFIBUS
1.PROFINET与PROFIBUS从狭义上比,没有可比性,因为他们的物理接口不同,电气特性,不同,波特率不同,电气介质特性不同等等.这样两者的协议是完全没有关联性的,唯一的关联性就是两者都是PI组 ...
- Multi-tasking RTOS for microprocessors with limited memory by saving only a single return address per task during context switching
A real-time operating system (RTOS) for use with minimal-memory controllers has a kernel for managin ...
- WPF中取得预定义颜色
原文:WPF中取得预定义颜色 使用XAML代码取得.net预定义颜色:<Page xmlns="http://schemas.microsoft.com/winfx/2006/x ...
- 简明Python3教程 8.控制流
简介 迄今为止我们见到的所有程序总是含有一连串语句并且python忠实的顺序执行它们. 那么如何改变它们的执行顺序呢?例如你希望程序根据不同情况作出不同反应,按照当前时间分别 打印出’Good Mor ...
- WPF 3D中多个模型如何设置某一个在最前?
原文:WPF 3D中多个模型如何设置某一个在最前? 问题:我们的模型包括导入的3D solid模型和axis坐标轴模型,当模型旋转的时候,3D会将axis挡住. 期望:axis一直在最前面,不会被3D ...
- Some Very Good VC++/MFC Resources Besides Codeproject.com
Some Very Good VC++/MFC Resources Besides Codeproject.com http://www.naughter.com/ (VC++/MFC huge co ...
- ObjectDataProvider
<Window.Resources> <ObjectDataProvider x:Key="personList" ObjectType="{x:Typ ...
- C# IDisposable接口的使用
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...