这个问题意味着语言正交(因为缺乏冗余)特征。 C ++ 中的引用(从不为null [1])可以用指针实现,而编译器检查语义差异。像Java或C#这样的语言只有引用(可能为null)但没有指针而C则反过来。因此,对于完整的语言来说,这是足够的。 C ++中的行为是否足够正交?
[1]您可以取消引用nullptr
,但这是未定义的。
答案 0 :(得分:1)
由于参考折叠规则(§8.3.2),引用已成为 非常有用;他们现在支持“完美转发”的东西 可能有指针。例如:
template<typename T>
class some_container
{
public:
// ... lots of other stuff
template<typename... Args>
void emplace_back(Args&&... args)
{
T* ptr = find_slot_for_new_data();
new (ptr) T( std::forward<Args>(args)... );
}
};
这将构建一个T
就地,(emplace_xxx
是委托构造函数)
并且它将使用“完美转发”这样做,即;
T&&
的 T
将保留:
使用指针无法做到这一点。
答案 1 :(得分:-2)
引用只不过是C ++中更严格的指针,因为您可以通过获取其地址来“转换”对指针的引用。 这远不是说它们是多余的,但它们与正交相反。他们基本上做同样的事情。
答案 2 :(得分:-2)
这是指针和要考虑的引用之间的区别。
.rdd
对战
#include <vector>
int main() {
// Compiles and it contains pointers to ints
std::vector<int*> vpInts;
return 0;
}
第二种情况是非法的,特别是在MSVS的MSVS2017 CE编译错误中显示。
#include <vector>
int main() {
// Does not compile
std::vector<int&> vrInts;
return 0;
}
基本上在C ++中,指针本身是一个声明的变量,它占用堆栈或堆上的内存,其中引用可能会或可能不会引用已经创建的对象或已经在内存中的变量。这取决于编译器如何处理它;一些编译器将通过在寄存器中输入和弹出值来使用移动语义来优化内存占用,而指针变量将始终占用指定的内存量。有一些相似之处,即指针确实指向另一个变量或对象的内存地址,并且引用引用已创建的另一个变量或对象的实例的内存地址。