c++ 通过引用传递函数-如何获取地址?

vwkv1x7d  于 2023-06-25  发布在  其他
关注(0)|答案(1)|浏览(172)

新手在c++和学习的乐趣。我仍然在努力理解引用和解引用语法,所以如果你正在阅读这篇文章,请发发善心,如果可以的话,请帮助解释一下。通常我理解=& foo返回对象foo的引用。一个&foo的引用应该能够像指针一样显示它所引用的对象的地址。因此,这可以用来赎回foo的地址:

//EXAMPLE 1 - works as expected?
void useFooRef(int &foo) {    
    cout << "using foo @ " << &foo << endl; //using foo @ 0x16eebb4e8
    //no warning here!
}

int foo = 1;

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

但是如果foo是我传递的一个函数,那么将它作为指针接收并提取它的地址似乎没问题;尽管如此,我还是读到过通过引用传递以避免传递空指针更安全。但是如果我这么做了,我会得到一个编译器警告...

//EXAMPLE 2
void useFooPtr(int (*foo)()) {
    cout << "using foo @ " << &foo << endl; //using foo @ 0x16fb634c8
    //no warning here!
};

void useFooRef(int (&foo)()) {
    cout << "using foo @ " << &foo << endl; //using foo @ 1
    //warning: 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++的心理Map是,变量名包含一些关于它自己的内存槽的元数据,引用包含它所引用的内存槽,指针包含它自己的内存槽,它持有它所指向的东西的槽。当一个函数接收到一个引用时,这个元数据看起来会是什么样的?一个指针在一个函数被传递的情况下,以及为什么可以使用&foo提取内存地址时,它是一个简单的int作为引用传递在示例1中,但不是当它是一个函数作为引用传递在示例2中...即使foo * 的地址在两种情况下都可以提取,如果它是作为指针接收的话?

wn9m85ua

wn9m85ua1#

std::cout::operator<<没有int (*foo)()的重载版本,因此它使用std::cout::operator<<(bool)并输出

std::cout << static_cast<bool>(&foo)  // 0 or 1.

警告:在定义良好的C代码中,引用不能绑定到解引用的空指针
这不是一个完整的警告文本。老实说,阅读不完整的警告是一个坏习惯,导致失败的研究。完整的警告文本非常清楚:
警告:在定义良好的C
代码中,引用不能绑定到解引用的空指针;* * 指针可以被假定为总是转换为true**[-Wundefined-bool-conversion]
众所周知,引用是现有对象的别名,其地址可能不是nullptr。编译器警告您它将始终输出1。GCC还提出了一个明确的警告:
警告:编译器可以假设'foo'的地址永远不会为NULL [-Waddress]

void useFooPtr(int (*foo)()) {
    cout << "using foo @ " << &foo << endl; //using foo @ 0x16fb634c8
    //no warning here!
};

foo @ 0x16fb634c8-这里输出局部变量foo的地址。函数地址由std::cout << foo输出,它也将输出foo @ 1
如果要输出函数的地址,请将其强制转换为void*

std::cout << reinterpret_cast<void*>(foo)

相关问题