C++ 我什么时候使用参考资料?
我对引用的理解是,它们是已经存在的变量的别名-它们不能为null。当修改原始输入时,它们对于函数调用很有用,因为引用被认为比指针更安全 除了上述情况以及引用是强制性的情况外,是否有其他原因/用例使用引用,而不是引用所指向的现有变量C++ 我什么时候使用参考资料?,c++,reference,C++,Reference,我对引用的理解是,它们是已经存在的变量的别名-它们不能为null。当修改原始输入时,它们对于函数调用很有用,因为引用被认为比指针更安全 除了上述情况以及引用是强制性的情况外,是否有其他原因/用例使用引用,而不是引用所指向的现有变量 编辑:请注意,除了上述内容之外,我还说了。这意味着我想知道在调用函数之外,什么时候else引用是有用的,什么时候不是必需的(我已经知道了)。我还特别想知道什么时候引用优于原始变量,而不是指针(我已经从另一个问题中学到了在两个变量之间进行选择时“可以使用引用,必须使用指
编辑:请注意,除了上述内容之外,我还说了。这意味着我想知道在调用函数之外,什么时候else引用是有用的,什么时候不是必需的(我已经知道了)。我还特别想知道什么时候引用优于原始变量,而不是指针(我已经从另一个问题中学到了在两个变量之间进行选择时“可以使用引用,必须使用指针”)在可以使用引用的地方使用引用,而不是指针。除非您想要操纵低级别内存,否则您不应该处理指针。另一种用法是使用new作为指针并传递该指针的引用,将主数据保留在堆上。但有了新的独特的、共享的和弱的组合,即使这是不需要的。唯一需要指针的地方是当对象可以为NULL ptr时,因为引用不能为NULL。除非有人以不正当的方式扭曲了代码,否则您可以安全地假定引用是有效对象。假设您有一个大型结构,或者一个
std::vector
或者一个std::string
对象,然后将该值传递给函数。这意味着对象被复制,这对于大型对象(比如几百万个条目的向量)来说可能效率很低。然后您可以使用对常量对象的引用,例如std::vector const&my_object
引用比指针更安全是一种常见的误解,但这是一种误解。生成空引用和其他非法引用同样容易。在炸毁你的程序之前,这些可能会传播很远。以下是一些例子:
- 创建空引用:只需取消引用空指针即可将结果传递给需要引用的对象
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(); }
关键是,上面的代码不会在取消引用空指针时崩溃,它只会默默地创建一个空引用。这是合法的,因为取消引用空指针被定义为未定义的行为,并且创建空引用对于编译器来说是一件有效的事情 空引用将成功传递到class-Foo{ 公众: Foo():bar(null_ptr){} 无效设置大小(大小\u t新闻大小){ 删除条; bar=新整型[新闻大小]; } doSomething(){ myVec.push_back(bar[0]);//这将在push_back()实现中的某个地方爆炸,而不是在这里! } 私人: int*bar; std::载体myVec; }; void baz(){ 福美福; myFoo.doSomething(); }
,只有当它自己尝试使用引用来实际获取其背后的值时,它才会出错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
答案的另一个小部分:当对象的一小部分杂乱无章的选择以一种过大或完全错误的方式重复时:std::vector foo; foo->push_back(7); int&bar=foo[0]//完全合法 巴*=6//完全合法 foo->push_back(8)//完全合法
我们之所以使用参照系,是因为以下几点吗- 修改调用者函数的局部变量
- 用于传递大型参数
- 以避免对象切片
- 在函数中实现运行时多态性
有关详细信息,请参见如果要将大参数传递给函数或方法,或者如果要将其“存储”到对象中(而不复制),请使用引用。引用与指针具有相同的特性(关于多态性或rtti)。没有办法指出什么是“更好”或“更差”-引用或指针,一切都取决于您使用它们的上下文。ITT:OP询问“除了在函数调用中,我们在哪里使用引用”,每个人回答“在函数调用中”答案的一小部分:如果(x->is_a_foo(){foo&xf=static_cast(*x);xf.memberof_foo(…)…}
假设适当的T&r=a[++i].b[--j].m_T;…r(a)+r(b)
我们需要一种非混乱的方式来调用它两次(而不是两次修改i或j)。T::operator()