一、地址的讨论
1. 普通函数 (Regular Function)
- 是否有地址?
是。普通函数在编译后分配在程序的代码段(text segment),具有固定的内存地址。可以通过函数指针获取: - 地址是否会更改?
不会。在程序的生命周期内,普通函数的地址在代码段中是固定的,不会因运行时状态而改变。代码段是只读的,加载到内存后地址恒定。
2. 成员函数 (Member Function)
- 是否有地址?
是。成员函数(包括非静态成员函数)也有固定的代码地址,存储在代码段中。可以通过成员函数指针获取:
注意:调用成员函数需要对象实例(this指针),但函数本身的代码地址是固定的。 - 地址是否会更改?
不会。成员函数的代码在程序加载时分配在代码段,地址固定不变。无论通过哪个对象调用,函数的指令地址始终相同。
3. lambda函数 (Lambda Expression)
- 是否有地址?
是。lambda表达式在编译时被转换为一个匿名的函数对象(functor),其operator()有固定的代码地址。可以通过函数指针或std::function间接访问:
lambda的闭包对象可能存储捕获的变量,但其operator()的代码地址是固定的。 - 地址是否会更改?
不会。lambda的operator()实现存储在代码段,地址在程序运行期间不会改变。捕获变量的存储位置(栈或堆)可能变化,但不影响lambda函数的代码地址。
4. 仿函数 (Functor)
- 是否有地址?
是。仿函数是实现了operator()的类或结构体,其operator()是一个成员函数,存储在代码段,具有固定地址。类似成员函数,可通过成员函数指针访问: - 地址是否会更改?
不会。仿函数的operator()代码在代码段中,地址固定不变。仿函数对象的实例(包含数据)地址可能随对象创建/销毁变化,但operator()的代码地址恒定。
故调用的时候不用担心调不到函数,反而要担心里面的变量会不会已经失效,从而引发coredump