2

举个例子。我创建了一个名为 的函数指针s,将其设置为f并调用它。这当然编译得很好:

void f() {}

int main() {

    void (*s)();

    s = f;

    s();

}

但是以下一个示例为例,我s现在将其声明为“函数引用”(如果它被称为)并设置为f内联。这也编译得很好:

void f() {}

int main() {

    void (&s)() = f;

    s();

}

这两种创建和初始化函数指针的方法有什么区别?请注意,当我使用引用语法时,我需要将其“内联”初始化为,f而使用“指针”语法,我可以双向进行。你也能解释一下吗?有了这个,你能解释一下它们在可用性方面的区别是什么,我什么时候必须使用一种形式而不是另一种形式?

4

5 回答 5

3

从根本上讲,跟注方没有明显区别。但是decl方面肯定会。正如您所指出的,引用必须初始化为引用something。这使它们“更安全”,但即使这样也不能保证“安全”。

函数指针根本不需要指向函数。它可能为 NULL,甚至未初始化(指向垃圾)。这并不重要,因为您以后可以随时更改它(这是您无法对引用进行的操作)。

void (*s)();  // uninitialized

或者

void (*s)() = NULL; // set to null

然后

void foo() 
{
}

s = foo;

你不能做任何参考。必须将引用初始化为一些东西,并且最好是一些有效的东西:

void (&f)() = foo;   // ok. also references foo().
void (&f)() = *s;    // also ok, but wait, is s valid?? does it have to be??

然而,即使在这里,函数引用也不能保证是安全的,只是更安全。你当然可以这样做:

void (*s)();
void (&f)() = *s;

你可能会得到一个编译器警告(我这样做,“在初始化之前使用”)但最后f仍然是对根本不是函数的“函数”的引用;只是指针中的随机堆栈垃圾s。更糟糕的是,因为无法重新分配引用。这东西总是指向垃圾。

于 2012-10-31T21:18:32.007 回答
2

差异与任何指针/引用的差异相同。

引用必须初始化并且以后不能重新分配:

int i,j;
int &r = i;
r = j; // i = j, not &r == &j

引用不能被视为与它们引用的对象不同的对象(与指针相反,指针是与它们指向的对象不同的对象)......

int i;
int *p = &i; // &p != &i
int &r = i;  // &r == &i

使用函数指针在语法上看起来与使用引用相同,但这是因为函数指针的特殊规则允许您在不取消引用的情况下使用它们。

于 2012-10-31T21:18:32.710 回答
2

您自己说过,不同之处在于,对于引用,您必须在声明时绑定它,这保证了引用始终引用有效对象。另一个区别是引用在声明后不能重新绑定,因此它们在整个生命周期中只引用一个对象。

除此之外,它们是相同的。我遇到了一些更喜欢引用的纯粹主义者,并说指针是不应该使用的 C 的遗迹。其他人更喜欢指针,因为他们更“明确”地说明它们是指针这一事实。

是否使用其中一种取决于您的需求。选择的方法是,尽可能使用引用,但如果您确实需要能够将其指向不同的函数,则使用指针。

于 2012-10-31T21:19:15.317 回答
0

对类型 P 的引用很像指向类型 P 的 const 指针(而不是指向 const P 的指针,这是不同的)。

碰巧的是,如果您的类型 P 是函数类型,那么它们的大多数不同方式并不重要。& 的行为略有不同,您可以直接将指针分配给非 const 指针,并且采用一个的函数可能不会采用另一个。

如果类型 P 不是函数类型,则会有很多其他差​​异——operator=、临时对象的生命周期等。

简而言之,答案是“不多”。

于 2012-10-31T21:17:57.997 回答
0
  1. 函数标识符是函数类型的表达式,但它们隐式转换为函数指针类型或函数引用类型。因此它们可以传递给引用或指针的构造函数以及指针的 operator=。

  2. 由于引用在语法上的行为类似于实例,因此无法对引用而不是被引用的对象进行操作。这就是为什么它们只能被初始化。顺便说一句,C++ 中的首选语法是带括号的,而不是=.

  3. 您应该尽可能使用引用,并且仅当您不能使用引用时才使用指针。原因是由于很多事情不能做参考(指向 NULL、更改参考对象、删除它等),因此在阅读代码时需要查找的事情更少。*此外,它还节省了一些&字符。

于 2012-10-31T21:20:14.903 回答