我想知道在某些情况下(取决于平台、编译器或代码环境等),引用是否比指针更高效?
引用是否比指针更高效?
不是的!并不一定。标准也没有这样说。
大多数编译器通过使用指针实现引用机制。C++中添加引用是为了支持运算符重载,而不是为了提高效率。
是的,可能会。我们只有在标准中存在一个明确或暗示的要求参考速度必须与所有情况下等效指针一样慢或更慢时才能说“不能”。由于标准不涉及这种性能细节,因此没有这样的要求。
例如,在低优化级别下,这将是合理的:
int n = 0;
int *np = &n;
for (int i = 0; i < 10000000; ++i) {
*np += i;
}
std::cout << n;
int n = 0;
int &nr = n;
for (int i = 0; i < 10000000; ++i) {
nr += i;
}
std::cout << n;
您可以将NULL传递给指针,因此您必须检查指针变量是否为NULL。这是引用比指针更高效的唯一原因。
除此之外,编译器将引用实现为指针。
是的,引用比指针更有效率。原因在于优化器。一般来说,现代CPU中最昂贵的操作之一就是从内存中读取数据。而在调用(非内联)函数后,编译器必须假设任何可能发生变化的内存变量都已经发生了变化。这意味着在下面的例子中,在调用Bar()
后,它必须重新加载p
:
class Foo {
int* p;
void Bar(); // defined somewhere else, not visible to compiler.
public:
Foo() { p = new int; Bar(); std::cout << *p; }
};
现在,这里的问题不是必须重新加载*p
,而是必须重新加载p
。它也可能会改变。现在看一下下面的代码:
class Foo {
int* p; // !
void Bar(); // defined somewhere else, not visible to compiler.
public:
Foo() { p = new int; int& r = *p; Bar(); std::cout << r; }
};
现在,编译器发现在Bar()
之后没有使用p
。使用的是r
,而且它可能被实现为指针。但是它不能被重新分配!因此,优化程序可以选择在函数调用期间保存r
。
C++引用在底层工作时类似于“永久解引用”指针。我预计性能应该是相同的。但是,由于引用的指针不能被重新分配,编译器可能能够应用更多无法用于原始指针的优化。
除了直接访问,没有什么比指针更有效率的了。但速度并不是引用存在的原因。