C/C++ 函数地址

2021-07-05  本文已影响0人  蓝笔头

C 函数

C 语言中没有类的概念,只有普通的函数。

#include <stdio.h>

void hello() {
    printf("hello world\n");
}

int main() {
    hello();
    printf(" hello = %p\n", hello);
    printf("&hello = %p\n", &hello);
}

控制台输出:

hello world
 hello = 0x559e5319f6f0
&hello = 0x559e5319f6f0

C++ 函数

C++ 函数有如下几种:

提示:虚函数主要是用来实现多态的。

普通成员函数

#include <iostream>
using namespace std;

class Base {
public:
    void a() { cout << "Base a()" << endl; }
};

int main()
{
    Base base1;
    base1.a();
    printf("&base1 = %p\n", &base1);
    printf("&Base::a = %p\n", &Base::a);
    return 0;
}

控制台输出:

Base a()
&base1 = 0x7ffda2c48a4f
&Base::a = 0x564baa84ba62

静态成员函数

#include <iostream>
using namespace std;

class Base {
public:
    static void a() { cout << "Base a()" << endl; }
};

int main()
{
    Base base;
    Base::a();
    printf("&base = %p\n", &base);
    printf(" Base::a = %p\n", Base::a);
    printf("&Base::a = %p\n", &Base::a);
    return 0;
}

控制台输出:

Base a()
&base = 0x7ffcb939558f
 Base::a = 0x555977ec2a4a
&Base::a = 0x555977ec2a4a

虚函数

#include <iostream>
using namespace std;

class Base {
public:
    virtual void a() { cout << "Base a()" << endl; }
    virtual void b() { cout << "Base b()" << endl; }
};

class Derive : public Base {
public:
    virtual void a() { cout << "Derive a()" << endl; } // 覆盖Base::a()
    virtual void c() { cout << "Derive a()" << endl; } // 覆盖Base::a()
};

1)直接取地址。

int main()
{
    cout << "-----------打印 class Base------------" << endl;
    Base base;
    printf("&base = %p\n", &base);
    printf("&Base::a = %p\n", &Base::a);
    printf("&Base::b = %p\n", &Base::b);

    cout << "-----------打印 class Derive------------" << endl;
    Derive derive;
    printf("&derive = %p\n", &derive);
    printf("&Derive::a = %p\n", &Derive::a);
    printf("&Derive::b = %p\n", &Derive::b);
    printf("&Derive::c = %p\n", &Derive::c);
    return 0;
}

控制台输出:

-----------打印 class Base------------
&base = 0x7ffeb36c8498
&Base::a = 0x1
&Base::b = 0x9
-----------打印 class Derive------------
&derive = 0x7ffeb36c8490
&Derive::a = 0x1
&Derive::b = 0x9
&Derive::c = 0x11

对于 virtual function(虚函数), 其地址在编译时期是未知的,所以对于 virtual member function(虚成员函数)取其地址,所能获得的只是一个索引值。

2)通过虚函数表取地址:

int main()
{
    typedef void(*Fun)(void);
    Derive d1;
    Fun** vt_ptr = (Fun**)&d1;

    cout << "-----------第一次打印虚函数地址------------" << endl;
    printf("&d1 : %p\n", &d1);
    for (int i = 0; i < 3; i++) {
        printf("[d1] vptr[%d] : %p\n", i, *(*vt_ptr + i));
    }

    Derive d2;
    vt_ptr = (Fun**)&d2;
    cout << "-----------第二次打印虚函数地址------------" << endl;
    printf("&d2 : %p\n", &d2);
    for (int i = 0; i < 3; i++) {
        printf("[d2] vptr[%d] : %p\n", i, *(*vt_ptr + i));
    }

    return 0;
}

控制台输出:

-----------第一次打印虚函数地址------------
&d1 : 0x7ffddd4fc1f8
[d1] vptr[0] : 0x5583e3383ccc
[d1] vptr[1] : 0x5583e3383c94
[d1] vptr[2] : 0x5583e3383d04
-----------第二次打印虚函数地址------------
&d2 : 0x7ffddd4fc1f0
[d2] vptr[0] : 0x5583e3383ccc
[d2] vptr[1] : 0x5583e3383c94
[d2] vptr[2] : 0x5583e3383d04

参考

上一篇 下一篇

猜你喜欢

热点阅读