为什么函数指针都有相同的值
Why do function pointers all have the same value?
例如:
using namespace std;
#include <iostream>
void funcOne() {
}
void funcTwo( int x ) {
}
int main() {
void (*ptrOne)() = funcOne;
cout << ptrOne << endl; //prints 1
void (*ptrTwo)( int x ) = funcTwo;
cout << ptrTwo << endl; //prints 1
int (*ptrMain)() = main;
cout << ptrMain << endl; //prints 1
}
有人知道这背后的原因吗?起初我认为这是因为函数不存在于内存中,因为我从未调用过它们,因此它们从未被添加到堆栈中。但是,即使是指向主函数的指针值也会打印出1。
函数指针不会隐式转换为void *
,这就是operator <<
重载的内容。
这一点在C++11§4.10/2:中有所遗漏
类型为"pointer to cv T"的prvalue,其中T是对象类型,可以转换为类型为"指针到cv void"的prvalue。将"指向cvT的指针"转换为"指向cv void的指针"的结果指向T类型对象所在的存储位置的开始,就好像该对象是T类型的最派生对象(1.8)(即,不是基类子对象)。空指针值转换为目标类型的空指针值。
函数类型不是对象类型。
此外,您甚至不能使用static_cast
来执行此操作。函数和对象可能生活在完全不同的地址空间中(这被称为哈佛体系结构),具有不同大小的指针。将函数指针转换为void *
可以使用reinterpret_cast
:它是"有条件支持的"(C++11§5.2.10/8)。这样的void *
只能用于打印或转换回原始函数指针类型。
这样使用它,否则它将转换为bool
类型。
cout << reinterpret_cast<void*>(ptrOne) << endl;
正如其他答案中所解释的,C++正在对函数指针进行一些自动类型强制。如果你只使用好的C风格printf
,你应该会得到你期望的结果:
#include <cstdio>
// ...
printf("func1: %pnfunc2: %pn", funcOne, funcTwo);
试试这个:
void (*ptrOne)() = funcOne;
cout << reinterpret_cast<void*>(ptrOne) << endl;
void (*ptrTwo)( int x ) = funcTwo;
cout << reinterpret_cast<void*>(ptrTwo) << endl;
int (*ptrMain)() = main;
cout << reinterpret_cast<void*>(ptrMain) << endl;
我认为通常情况下,函数重载规则意味着被调用的<<
的版本是operator<<(bool)
,这意味着:
cout << ptrOne << endl;
转换为:
cout << (ptrOne != NULL) << endl;
与相同
cout << true << endl;
相关文章:
- QMetaObject invokeMethod的基于函数指针的语法
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- c++r值引用应用于函数指针
- 模板函数指针和lambda
- 是否可以将llvm::FunctionType转换为C/C++原始函数指针
- 带有类的函数指针
- () 函子后面的括号,而不是函数指针?
- 全局作用域中函数指针的赋值
- 使用"Task"函数指针队列定义作业管理器
- 将成员函数指针作为参数传递给模板方法
- 如何创建对象函数指针C++映射?
- 匹配函数指针作为模板参数?
- 通过函数指针定义类范围之外的方法
- 存储在类中的函数指针
- C++从函数指针数组调用函数
- 将返回值存储在函数指针数组的指针中是如何工作的?
- 整数键映射到头文件中的成员函数指针
- 从类成员函数到类 C 函数指针的转换
- 如何将内联匿名函数分配给C++函数指针
- 将字符缓冲区强制转换为函数指针