提问人:Flash 提问时间:8/17/2010 最后编辑:einpoklumFlash 更新时间:7/4/2022 访问量:1040
什么是 C 语言中的引用?
What is a reference in C?
问:
我刚刚开始使用 C++,遇到了参考文献,还没有完全理解。
正如我所读到的,引用是对象的替代名称。为什么使用它而不是直接访问对象,因为对引用的任何操作都会直接反映在对象上......?
- 为什么以及何时使用它们?
- ist 是否像一个常量指针,每次使用时都会被引用......?
而且,它说
double& dr = 1; ---- says it is an error (some lavalue needed)
const double& cdr = 1; ---- says it is ok.
我没有正确理解它..所以请解释一下为什么会这样......
谢谢...:)
答:
引用基本上是一个看起来像对象的指针。获得 NULL 引用非常非常困难,尽管您可以浏览箍并创建一个。
关于您的示例,1 是右值或结果。它只是一个临时变量,无法修改。因此,你不能对它进行非常量引用。但是,您可以对它进行常量引用。这意味着您无法更改引用的值。
下面是创建 NULL 引用的示例。别这样!
int * x = (int *)NULL;
int & y = *x;
评论
*x
double& dr = 1; // 1.0 would be more clear
无效,因为被视为类型,因此,如果要引用该变量,则需要引用 so1
const double
const double
const double& dr = 1.0;
是正确的。
引用是最初在 C 代码中出现的另一种方式,如下所示
void fubarSquare(int *x){ int y = *x; *x = y * y; } // typical invocation int z = 2; fubarSquare(&z); // now z is 4
使用 C++ 中的引用,它会是这样的
void fubarSquareCpp(int& x){ x = x * x; } // typical invocation int z = 2; fubarSquareCpp(z); // now z is 4
这是一种更简洁的语法方式,它使用按引用调用参数,而不是使用 C 的符号星号/星号来指示指针并作为按引用调用参数......并直接在函数外部修改参数...
请看Bjarne Stoustrap的页面,其中介绍了C++是如何的,还有这里的技术常见问题解答
我同意你的看法。仅将引用用作别名不是很有用。 如果将其视为不可变指针,则会更有用。但实际上并没有那么有用。
实际上,它用于定义干净的接口。例如,当您定义:
int foo(const int& param);
你说 param 是 foo 中的只读参数。
不要忘记,您必须为引用赋值。
有关更多信息,请参阅参考中的 C++ faqlite
我的2C
评论
为什么要用它来代替直接 像任何操作一样访问对象 on 参考资料直接反映在 对象...?
C++ 按值传递参数,这意味着如果您有如下函数:
void foo(MyObject o) { ... }
默认情况下,C++ 将复制 ,而不是直接使用传入的对象。因此,引用的一个用途是确保您正在处理同一个对象:MyObject
void foo(MyObject &o) { ...}
或者,如果您不修改:o
void foo(const MyObject &o) { ... }
仔细阅读维基百科文章。总而言之,引用是指针的更友好版本,通常用于将对象作为引用传递到函数中,而不必担心空指针。
解释一下这个例子:
将表示为变量的数字视为一个变量。编译后,该数字被放入内存的全局部分,程序可以引用该部分,但不能修改。1
所以它的类型是:const int
double &dr = 1
正在尝试将 (对双精度的引用) 分配给 .由于 is 是一个常量,因此编译器将不允许你对它进行非常量引用。dr
const int 1
1
在第二行中:
const double &dr = 1
正在尝试分配(对双精度的常量引用).这之所以有效,是因为引用也是 const,因此可以指向 .dr
const int 1
const int
编辑在分配之前转换为 a。const int
const double
评论
1
int
const int
f()
A
1
int
1
int& i = 1;
int f(); int& i = f();
int&& i=1
引用改进了语法,因此不需要指针取消引用。 假设 Base 是一个类,该类可能派生自:
void someFunction(Base b)
{
b.function();
// b is a copy of what was passed - probably performance issues
// possible unintended object slicing - you only get the Base part of it
// no virtual function call
// no changes to b visible outside the function
}
void someFunction(Base* b)
{
b->function();
// a shortcut for (*b).function();
// b is the same object that was passed to the function
// possible virtual call
// changes visible outside the function
}
void someFunction(Base& b)
{
b.function();
// b is the same object that was passed to the function
// possible virtual call
// changes visible outside the function
}
引用类似于常量指针(不是指向常量的指针 - 即您可以更改对象,但不能更改为指向的内容)。const reference 是一个引用,通过它你可以执行可以在 const 对象上完成的操作。
引用也很好,因为你不能有空引用
引用的效用在将参数传递给函数的上下文中最为明显。
即,
int a;
func 定义: void foo (int& param) {param = 1;}
函数调用:foo(a);
“param”别名“a”的方式是干净的,它的意图很容易被此代码的读者以及编译器理解,编译器可以在内联引用所需的任何额外内存分配时进行优化。
引用是表示它们所引用的另一个对象的语言实体。非常量引用是左值,必须用左值初始化。它们可以像这样有用:
int& x=condition ? array[1] : array[2];
int& y=condition ? array[0] : array[3];
x+=y;
y=0;
当用作函数参数时,它们告诉调用方他必须传递一个可能由函数写入的左值:
void set1(int& x) { x=1; }
int foo;
set1(foo); // ok, foo is 1
set1(foo+1); // not OK, not lvalue
另一方面,Const 引用可以绑定到右值。在函数参数中,它们通常用于避免过多的复制:
void niceness(std::string s); // the string would be copied by its copy-ctor
void niceness(const std::string& s); // the caller's string would be used
请注意,这可能会也可能不会产生更快的代码。
当在普通代码中使用 const-references 时,它们也可以绑定右值,并且作为特殊规则,它们会延长它们绑定到的对象的生存期。这是您在代码中看到的内容:
const double& d=1; // OK, bind a rvalue to a const-ref
double& d=1; // Bad, need lvalue
所有引用都是多态的,就像指针一样:
class A { virtual void f(); }
class B : public A { void f(); }
B b;
A& ar=b;
ar.f(); // calls B::f()
所有引用都是别名,如指针:
int f(int& a, const int& b)
{
a=1;
return b;
}
int x;
f(x, 42); // ==42, foo=1
x=42;
f(x, x); // ==1 (not 42), foo=1
传递对函数的引用,然后让函数使用引用,几乎就像将指针传递给函数,然后让函数取消引用指针一样。在许多情况下,机器代码实现是相同的。但是,存在一些差异,尤其是在内联扩展的函数的情况下。如果通过引用将变量传递给内联函数,则编译器在扩展函数时通常能够替换变量本身,即使存储在机器寄存器中也是如此。相反,如果获取变量的地址并将其作为指向函数的指针传递,然后取消引用该函数,则编译器不太可能找出该优化,除非它不仅确定(至少对于函数的一个特定扩展)指针将始终指向该变量,而且还确定指针不会在其他任何地方使用(如果指针在其他地方使用, 变量不能保存在寄存器中)。
评论