我可以使用一个对象的指针或引用。我理解它们之间的区别在于指针需要手动删除,而引用仅在超出其作用域时才消失。
那么何时使用它们?它们之间有什么实际差异?
这些问题都没有回答我的疑虑:
我可以使用一个对象的指针或引用。我理解它们之间的区别在于指针需要手动删除,而引用仅在超出其作用域时才消失。
那么何时使用它们?它们之间有什么实际差异?
这些问题都没有回答我的疑虑:
引用基本上是带有限制的指针(必须在创建时进行绑定,不能重新绑定/为空)。如果您的代码使用这些限制很有意义,那么使用引用而不是指针允许编译器警告您意外违反它们。
这很像 const
修饰符:语言可以存在没有它,它只是一种额外的功能,使开发安全代码更容易。
const
的比较与指针本身有关:const指针和引用并不相同(更多信息请参考这里:http://www.parashift.com/c++-faq-lite/references.html#faq-8.5 )。这只是一个强制实施特定语义的语言特性的示例,让你不必自己去做。 - suszterpatt我需要删除指针并在作用域结束前保留引用。
不,那是完全错误的。
使用new
分配的对象必须使用delete
来删除[*]。未使用new
分配的对象不应被删除。可以有一个指向未使用new
分配的对象的指针,也可以有一个指向使用new
分配的对象的引用。
指针或引用是访问对象的方式,但它们本身不是对象,并且与对象的创建方式无关。概念上的区别在于,引用是对象的名称,而指针是包含另一个对象地址的对象。实际上,选择使用哪种方法的差异包括每种方法的语法以及引用不能为null且不可重新设置。
[*] 使用delete
。使用new[]
分配的数组必须使用delete[]
删除。有一些工具可以帮助跟踪已分配的资源并为您进行这些调用,称为智能指针,因此直接调用应该很少见,而只需安排进行即可,但是仍然必须执行。
suszterpatt已经给出了很好的解释。如果你想要一个易记的经验法则,我建议如下:
如果可以使用引用,就尽量使用引用,只有当你无法避免时才使用指针。
更简短的说:优先选择使用引用而非指针。
new
创建指针时,会保留其内存并持久化直到您调用delete
函数来释放内存。但是,标识符的生命周期仍限于代码块的结尾。如果在函数中创建对象并将它们附加到外部列表中,则这些对象可能会在函数返回后安全地留在内存中,并且您仍然可以引用它们而无需标识符。void UmbraEngine::addModule (UmbraModule * module) {
modules.push(module);
module->id = modules.size() - 1;
}
获取一个:
UmbraModule * UmbraEngine::getModule (int id) {
for (UmbraModule **it=modules.begin(); it != modules.end(); it++) {
if ((*it)->id == id) return *it;
}
}
int main() {
UmbraEngine e;
for (int i = 0; i < 10; i++) {
e.addModule(new UmbraModule());
}
UmbraModule * m = e.getModule(5); //OK
cout << m << endl; //"0x127f10" or whatever
for (int j = 0; k < 10; j++) {
UmbraModule mm; //not a pointer
e.addModule(&mm);
}
m = e.getModule(15);
cout << m << endl; //{null}
}
new
实例化模块,我不需要关心模块的寿命 :). 这就是它的基本含义-通过指针,你可以拥有长寿的对象,而不需要标识符(或名称)来引用它们 :).
另一个简单而美好的例子如下:
void getVal (int * a) {
*a = 10;
}
int main() {
int b;
getVal(&b);
return b;
}
让我们先回答最后一个问题。然后第一个问题会更有意义。
问: "指针和引用之间的实际区别是什么?"
答:引用只是另一个变量的本地别名。如果您通过引用传递参数,则该参数与调用语句中列出的变量完全相同。但是,在内部,指针和引用通常没有区别。引用提供了“语法糖”,使您可以减少输入的数量,当您真正想要访问给定变量的单个实例时。
问:“我应该在何时使用它们?”
答:这将是个人偏好的问题。这是我遵循的基本规则。如果我需要在另一个范围内操作变量,并且该变量是一个内置类型,应该像内置类型一样使用的类(即std :: string等),或者是const类实例,则我通过引用传递。否则,我将通过指针传递。
嗯...不完全正确。作用域的是标识符。当你使用new
创建一个对象时,但其标识符的作用域结束后,你可能会遇到内存泄漏(或者不会 - 这取决于你想要实现什么) - 对象仍然在内存中,但你已经无法引用它了。
区别在于指针是内存中的地址,因此如果你有以下代码:
int * a = new int;
a
是一个指针。你可以打印它 - 你会得到类似 "0x0023F1" 的东西 - 它只是一个地址。它没有值(尽管一些值存储在该地址的内存中)。
int b = 10;
b
是一个变量,它的值为 10。如果你打印它,你会得到 10
。
现在,如果你想让 a
指向 b
的地址,你可以这样做:
a = &b; //a points to b's address
或者,如果您想让a
指向的地址具有b
的值:
*a = b; //value of b is assigned to the address pointed by a
#include <iostream>
using namespace std;
int main()
{
int * a = new int;
int b = 10;
cout << "address of a: " << a << endl;
cout << "address of b: " << &b << endl;
cout << "value of a: " << *a << endl;
cout << "value of b: " << b << endl;
a = &b; //comment/uncomment
//*a = b; //comment/uncomment
cout << "address of a: " << a << endl;
cout << "address of b: " << &b << endl;
cout << "value of a: " << *a << endl;
cout << "value of b: " << b << endl;
}
正如我的C++老师所说,指针指向内存位置,而引用是别名。因此,它们的主要优点是可以像对象名称一样在作用域中使用,即使该对象不可用也可以通过引用传递。
虽然指针可以重定向到其他位置,但引用就像常量指针一样,不能被重定向。因此,在函数中不能使用引用来遍历数组等。
然而,指针作为一个独立的实体占用一些内存,而引用与所引用的对象相同,不占用任何额外的空间。这是它的优点之一。
我还读到过引用的处理时间更短,
例如:
int & i = b ;
i++ ; 比
int * j = b ;
(*j) ++ ;
花费的时间更少,但我还需要确认这一点。如果有人能够证实这个说法,那就太好了。
欢迎留言 :)