You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中按引用传递函数:如何获取其内存地址?

C++函数引用与指针的地址获取疑问

我是C++新手,出于兴趣学习,目前仍在理解引用和解引用语法。我理解&foo会返回对象foo的引用,且通过&foo应该能像指针一样获取引用指向对象的内存地址,如下例能正常获取foo的地址:

//EXAMPLE 1 - 符合预期
void useFooRef(int &foo) {    
    cout << "using foo @ " << &foo << endl; //输出:using foo @ 0x16eebb4e8
    //无警告!
}

int foo = 1;

int main() {
    useFooRef(foo);
    return (0);
}

但当foo是函数时,用指针接收能正常获取地址,而我了解到按引用传递更安全可避免空指针,但用引用接收时会出现编译器警告,输出结果异常:

//EXAMPLE 2
void useFooPtr(int (*foo)()) {
    cout << "using foo @ " << &foo << endl; //输出:using foo @ 0x16fb634c8
    //无警告!
};

void useFooRef(int (&foo)()) {
    cout << "using foo @ " << &foo << endl; //输出:using foo @ 1
    //警告:reference cannot be bound to dereferenced null pointer in well-defined C++ code
};

int foo() {
    return (3);
};

int main() {
    useFooPtr(foo);
    useFooRef(foo);
    return (0);
}

我目前对C++的认知是:变量名包含自身内存槽的元数据,引用存储指向对象的内存槽地址,指针有自身内存槽,存储指向对象的内存槽地址。我想请教:传递函数时,引用和指针接收的元数据有何不同?为何普通int引用能通过&foo获取地址,函数引用却不行,而函数指针在两种场景下都能正常获取地址?


核心差异:函数与普通变量的本质区别

首先要明确:函数不是对象,而int这类普通变量是对象。C++里的引用分为「对象引用」和「函数引用」,两者的行为因为目标的本质不同而有差异。

1. 普通int引用的&foo行为

对于int &foo这种对象引用:

  • 引用本身是变量的别名,没有独立的内存槽(标准未要求为引用分配内存,编译器通常会优化掉)。
  • 当你写&foo时,实际上是取被引用对象的地址,也就是原int foo的内存地址,这和直接取原变量地址完全等价,所以输出正常,无警告。

2. 函数指针与函数引用的&foo行为

先理清函数名的隐式转换:

  • 函数名foo在大多数语境下会隐式转换成指向自身的函数指针(比如传给useFooPtr时,foo自动变成&foo)。
  • 但&foo对于函数来说,直接返回的就是函数指针(函数本身没有内存槽,函数的"地址"就是其机器码在内存中的起始位置)。
函数指针的情况

int (*foo)()是一个函数指针变量,它有自己的内存槽,存储的是函数的地址。

  • 当你写&foo时,取的是这个指针变量自身的内存地址,也就是栈上存储函数指针的那个位置的地址,所以输出是一个正常的栈地址,无警告。
函数引用的情况

int (&foo)()是函数的别名,和对象引用一样,它没有独立的内存槽。

  • 当你写&foo时,按照C++标准,函数引用的&操作会直接返回函数的指针(因为函数本身没有地址可被取,引用只是别名)。但这里出现了问题:cout无法直接输出函数指针,会把它当作bool类型处理,非空函数指针会被转换成true,也就是输出1,这就是你看到的异常结果。
  • 至于编译器警告,这是部分编译器的过度提示,因为你绑定的是合法的函数,并非空指针,这个警告可以忽略。

3. 关于"元数据"的认知修正

你的认知有一点偏差:

  • 引用没有独立的内存槽(标准未规定,编译器可能会在某些场景下为引用分配内存,但这是实现细节,不是标准行为),它只是被引用对象的别名。
  • 函数本身不是对象,没有"内存槽",函数的地址是其机器码在程序内存中的起始位置,不是某个变量的存储地址。

内容的提问来源于stack exchange,提问作者joshstrike

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 16:53:14