我对引用的理解是它们是已存在变量的别名 - 它们不能为空。它们在修改原始输入时对函数调用很有用,因为引用被认为比指针更安全。
除了上述情况以及必须引用的情况之外,还有其他原因/用例使用引用而不是引用所指向的已存在的变量吗?
编辑:请注意,我说除了以上。含义我想知道其他引用何时有用 - 如果不需要 - 在调用函数之外(我已经知道)。我还特别想知道什么时候引用比原始变量更受欢迎,不超过指针(我已经从另一个问题中学到了“当你可以时使用引用,当必须时使用引用”)两者之间)。
答案 0 :(得分:4)
假设您有一个大型结构,或std::vector
或std::string
对象,并将其按值传递给函数。这意味着该对象被复制,这对于大型对象来说可能效率很低(比如说几万个条目的向量)。然后你可以使用对常量对象的引用,例如std::vector<SomeType> const& my_object
。
答案 1 :(得分:3)
我们因为以下事项而使用Reference
修改调用函数的局部变量。
用于传递大型参数。
避免对象切片。
在函数中实现运行时多态性。
有关详细信息,请参阅http://www.geeksforgeeks.org/when-do-we-pass-arguments-by-reference-or-pointer/
答案 2 :(得分:0)
使用引用而不是指针。除非你想操纵低级内存,否则你不应该处理指针。另一种用法是将主数据保存在堆上,使用new作为指针并传递该指针的引用。但是使用新的unique_ptr,shared_ptr和weak_ptr组合甚至不需要。需要指针的唯一地方是当对象可以为nullptr时,因为引用不能为NULL。您可以放心地假设引用是一个有效的对象,除非有人以不正当的方式扭曲代码。
答案 3 :(得分:0)
一种常见的误解是引用比指针更安全,但这是一种误解。生成空引用和其他非法引用同样容易。这些可以在炸毁你的程序之前传播很远。以下是一些例子:
创建空引用:只需取消引用空指针即可将结果传递给需要引用的内容。
class Foo {
public:
Foo() : bar(null_ptr) {}
void setSize(size_t newSize) {
delete bar;
bar = new int[newSize];
}
doSomething() {
myVec.push_back(bar[0]); //This will blow up somewhere in the push_back() implementation, not here!
}
private:
int* bar;
std::vector<int> myVec;
};
void baz() {
Foo myFoo;
myFoo.doSomething();
}
关键是上面的代码不会在您取消引用空指针的位置爆炸,它只会默默地创建一个空引用。这是合法的,因为取消引用空指针被定义为未定义的行为,并且创建空引用是编译器要做的有效事情。
null引用将成功传递给std::vector<>::push_back()
,只有在它本身尝试使用引用实际获取其后面的值时才会进行段错误。
悬空引用:只需让引用的对象在引用之前结束其生命周期。同样,问题与指针一样:
std::vector<int> foo;
foo->push_back(7);
int& bar = foo[0]; //perfectly legal
bar *= 6; //perfectly legal
foo->push_back(8); //perfectly legal
cout << "The answer is: " << bar; //BOOM, bar is dangling, undefined behavior results
注意:此代码实际上可能按预期运行,就像访问悬空指针的代码可以按预期重复运行一样。
超出范围的引用:与指针一样容易:
std::vector<int> array;
array.resize(7);
int& bar = array[7]; //undefined behavior, even if the compiler detects this, it will silently ignore it
bar = 42; //since this is undefined behavior, the compiler may optimize away this line
与悬空引用一样,此代码可能运行得很好,但它可能无法完成您的想法。由于优化,它甚至可能无法写入超出范围的元素。或者它可能会破坏堆,堆栈或两者,或者无声地计算错误的结果。只是吹嘘段错误实际上是最不可能的结果。
如您所见,最后两个示例代码甚至不需要任何显式指针,它们只使用现代的,闪亮的C ++样式数据结构。然而,它们导致未定义的行为,不会在调用它的地方发生。非法引用可以在创建明显不良事件之前从其创建的地方传播任何距离。这正是人们使用指针所害怕的原因;指针和引用的危险是一样的。
所以,真的,使用对你有意义的引用。但不要依赖它们“安全”。