函数指针与虚函数表

函数指针

定义方式

typedef 返回值类型(* 新类型名称)(参数列表)

typedef char (*PTRFUN)(int);
PTRFUN pFun;
char glFun(int a){ return;}
void main()
{
    pFun = glFun;
    (*pFun)(2);
}

调用方式:

  1. 直接把函数指针变量当作函数名,然后填入参数
  2. 将函数指针的反引用作为函数名,然后填入参数

上面的PTRFUN也可直接进行以下调用:

 PTRFUN(2);

函数调用方式

函数名就是函数的地址,是一个编译时的常量,“函数连接”的本质就是把函数地址绑定到函数的调用语句上。

静态连接:一般的函数调用语句可以在编译的时候就完成这个绑定,这就是静态连接。

运行时连接&动态连接:

函数指针可以理解为一个新的类型,由其定义的变量,与其他变量一样,在编译期间是没有值的,因此函数指针与函数体的绑定关系只有到了运行时才确定。

对于函数指针数组,此特征表现的尤为明显,见《高质量程序设计指南》P135

class CTest
{
   public:
         void f(void){cout<<"CTest::f()"<<endl;} //普通成员函数
         static void g(void) {cout<<"CTest::g()"<<endl;} //静态成员函数
         virtual void h(void) {cout<<"CTest::h()"<<endl;} //虚拟成员函数

    private:
         //..........
};

void main()
{
   typedef void (*GFPtr)(void);     //定义一个全局函数指针类型
   GFPtr fp = CTest::g;                 //取静态成员函数地址的方法和取一个全局函数的地址相似
   fp();                                         //通过函数指针调用类静态成员函数
   typedef void (CTest::*MemFuncPtr)(void)//声明类成员函数指针类型
   MemFuncPtr mfp_1 = &CTest::f;               //声明成员函数指针变量并初始化
   MemFuncPtr  mfp_2 = &CTest::h;             //注意获取成员函数地址的方法
   CTest theObj;
   (theObj.*mfp_1)();                //使用对象和成员函数指针调用成员函数
   (theObj.*mfp_2)();
   CTest* pTest = &theObj;
   (pTest->*mfp_1)();              //使用对象指针和成员函数指针调用成员函数
   (pTest->*mfp_2)();
}

  

时间: 2024-10-09 22:33:08

函数指针与虚函数表的相关文章

虚函数指针和虚函数表

1 #include <iostream> 2 3 using namespace std; 4 5 class father 6 { 7 public: 8 father(int x):m_idata(x) 9 {} 10 11 virtual void show(int idata) 12 { 13 cout << "papa" << endl; 14 cout << idata-20 << endl; 15 } 16 v

深入剖析C++多态、VPTR指针、虚函数表

在讲多态之前,我们先来说说关于多态的一个基石------类型兼容性原则. 一.背景知识 1.类型兼容性原则 类型兼容规则是指在需要基类对象的任何地方,都可以使用公有派生类的对象来替代.通过公有继承,派生类得到了基类中除构造函数.析构函数之外的所有成员.这样,公有派生类实际就具备了基类的所有功能,凡是基类能解决的问题,公有派生类都可以解决.类型兼容规则中所指的替代包括以下情况: 子类对象可以当作父类对象使用 子类对象可以直接赋值给父类对象 子类对象可以直接初始化父类对象 父类指针可以直接指向子类对

C++对象内存模型2 (虚函数,虚指针,虚函数表)

从例子入手,考察如下带有虚函数的类的对象内存模型: 1 class A { 2 public: 3 virtual void vfunc1(); 4 virtual void vfunc2(); 5 void func1(); 6 void func2(); 7 virtual ~A(); 8 private: 9 int m_data1, m_data2; 10 }; 11 12 class B : A { 13 public: 14 virtual void vfunc1();; 15 vo

C++ 多态、虚函数机制以及虚函数表

1.非virtual函数,调用规则取决于对象的显式类型.例如 A* a  = new B(); a->display(); 调用的就是A类中定义的display().和对象本体是B无关系. 2.virtual函数,具体调用哪个版本,取决于虚函数表.例如 A* a = new B(); a->v_display(); 这个时候,对象a就需要查找自身的虚函数表,表中的v_display()是一个函数指针,可能指向不同类中的对应的v_display函数并调用对应版本的v_display.一般而言,如

C++学习 - 虚表,虚函数,虚函数表指针学习笔记

虚函数 虚函数就是用virtual来修饰的函数.虚函数是实现C++多态的基础. 虚表 每个类都会为自己类的虚函数创建一个表,来存放类内部的虚函数成员. 虚函数表指针 每个类在构造函数里面进行虚表和虚表指针的初始化. 下面看一段代码: // // main.cpp // VirtualTable // // Created by Alps on 15/4/14. // Copyright (c) 2015年 chen. All rights reserved. // #include <iostr

C++程序设计POJ》《WEEK6 多态与虚函数》《多态的实现原理》《虚函数表》

“多态”的关键在于通过基类指针或引用调用一个虚函数时,编译时不确定到底调用的是基类还是派生类的函数,运行时才确定---- 这叫“动态联编”.“动态联编” 底是怎么实现的呢? #include<iostream> using namespace std; class Base { public: int i; virtual void Print() { cout << "base:print"; } }; class Derived :public Base {

C++中3种多态实现机制之虚函数表

上期我们简单的讲解了利用RTTI来实现多肽,这期我们就来聊聊利用虚函数的方法来实现多肽. 1.什么是虚函数 在某基类中声明为 virtual 并在一个或多个派生类中被重新定 义的成员函数,用法格式为:virtual 函数返回类型 函数名(参数表) {函数体}:,实现多态性,通过指向派生类的基类指针或引用,访问派生类中同名覆盖成员函数 2.实现多肽的条件 简单的说就是:基类的指针或引用指向子类对象,当子类中成员函数和基类成员函数:函数名相同,参数列表相同,返回值相同,并且基类该函数为虚函数时,基类

C++入门学习——虚函数表介绍

多态 多态是指使用相同的函数名来访问函数不同的实现方法,可以简单概括为"一种接口,多种方法". C++支持编译时多态(也叫静态多态)和运行时多态(也叫动态多态),运算符重载和函数重载就是编译时多态,而派生类和虚函数实现运行时多态. 静态多态与动态多态的实质区别就是函数地址是早绑定还是晚绑定.如果函数的调用,在编译器编译期间就可以确定函数的调用地址,并生产代码,是静态多态(编译时多态),就是说地址是早绑定的.而如果函数调用的地址不能在编译器期间确定,需要在运行时才确定,这就属于晚绑定,是

C++虚函数表与虚析构函数

1.静态联编和动态联编联编:将源代码中的函数调用解释为要执行函数代码. 静态联编:编译时能确定唯一函数.在C中,每个函数名都能确定唯一的函数代码.在C++中,因为有函数重载,编译器须根据函数名,参数才能确定唯一的函数代码. 动态联编:编译时不能确定调用的函数代码,运行时才能.C++中因为多态的存在,有时编译器不知道用户将选择哪种类型的对象,因此无法确定调用的唯一性,只有在运行时才能确定. 2.虚成员函数,指针或引用,动态联编指针或引用才能展现类的多态性.当类中的方法声明为virtual时,使用指