zoukankan      html  css  js  c++  java
  • 类成员函数指针的特殊之处(成员函数指针不是指针,内含一个结构体,需要存储更多的信息才能知道自己是否virtual函数)

    下面讨论的都是类的非静态成员函数。

    类成员函数指针的声明及调用:

    1
    2
    3
    4
    5
    6
    7
    //pr是指向Base类里的非静态成员函数的指针
    //其行参为(int, int),返回值为void
    void (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<<' '<<sizeof(&Foo1)<<' '
            <<"Foo2: "<<Foo2<<' '<<sizeof(&Foo2)<<' '
            <<"p1:   "<<p1<<' '<<sizeof(p1) <<' '
            <<"p2:   "<<p2<<' '<<sizeof(p2) <<' '
            <<"p3:   "<<p2<<' '<<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.“

    这篇文章较深入地研究了成员函数指针,及比较了普通成员函数指针和虚函数指针在转化的过程中存在那些差异。

  • 相关阅读:
    Excel的VBA小练习
    敏捷和产品
    Ubuntu的系统应用
    也晒晒生产力工具:键盘
    SQLServer 2012 Ent 安装失败,另辟蹊径
    还是要精简开发呀,VS2015太大,VS2010不想装
    必须夸夸Sublime,大文件打开
    过节了,开源中国歪歪了!!!
    关于VisualStudio2010发布项目问题
    Visual Studio 各个版本汇总
  • 原文地址:https://www.cnblogs.com/findumars/p/6328391.html
Copyright © 2011-2022 走看看