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.“

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

  • 相关阅读:
    C#通过正则表达式统计词频的一个方法
    本地服务器远程连接其它数据库
    拼字符串成为时间,和两个计算时间点的中间值
    删除文件夹里的图片,打印删除日志
    行转列SQL语句
    加载出一个有层次的下拉框
    查询结果列传行
    【Java&Python双管齐下复健002】回文数和反转数
    【Java&Python双管齐下复健001】冒泡排序和质数判断
    【LeetCode记录】初级算法:数组之删除排序数组中的重复项
  • 原文地址:https://www.cnblogs.com/findumars/p/6328391.html
Copyright © 2011-2022 走看看