您何时想在C ++中使用指针与值?

时间:2009-10-13 23:44:13

标签: c++ pointers

我来自Java并试图学习C ++。

据我所知,使用指针非常类似于引用变量在Java中的工作方式,因为您将内存地址传递给值。所以我觉得我对他们有了很好的理解。我也明白这些变量存储在堆上。

但是,我发现还有另一种方法可以在C ++中声明变量,而不需要新的操作符/指针执行以下操作:

Employee boss("Frank");

这将创建一个以“Frank”作为参数的Employee值。这些变量存储在堆栈中。

那么,你有两种截然不同的创建变量的方式,它们都有自己独特的行为(也有内存管理?)。

我的问题是,什么时候使用指针VS值是否合适?什么是最佳做法?我怎么知道我想以什么方式在大多数时候声明我的变量?

7 个答案:

答案 0 :(得分:6)

C ++指针的运行方式与Java对象完全相同,因为它们可能无效(NULL)并且传递给程序很便宜。

C ++引用是指针的一个薄包装器。它们不应该是无效的,但在某些情况下可能是无效的。例如,可以从NULL指针创建引用,或者可以删除它引用的内存。

在代码示例中,您提供:

Employee boss("Frank");

你正在使用一种叫做“价值”的东西。与指针和引用不同,值它们所代表的对象,而不是间接。

  

我的问题是,什么时候适当   使用指针VS [值]?   什么是最佳做法?应该怎样   我知道我想以什么方式申报   我的变量大部分时间都在吗?

C ++没有垃圾收集,因此在变量范围有限时使用值。例如,不是为new分配一个并且为过程中的每个变量释放delete,而是可以在堆栈上分配它们而不用担心内存。

答案 1 :(得分:4)

这里有两个不同的问题:创建对象,并引用它们。

创建

创建对象有两个地方:堆栈和堆。如果您使用您描述的语法:

Employee boss("Frank");

将在堆栈上创建它。如果你这样写:

Employee* boss = new Employee("Frank");

它将在堆上创建它。如果你不熟悉堆栈和堆的概念,那么成为一名优秀的C ++编码器是非常重要的,所以要了解它!

参考

参考对象有些不同。无论如何创建对象,都可以使用指针或引用(或仅仅是标准变量)来引用它。尽管存在重要的差异,但在C / C ++中使用引用和指针实际上是非常相同的。

使用指针或引用时,对象的副本

// No copies made:
Employee& frank = boss;  // Using References
Employee* frank = &boss; // Using a Pointer

当您不使用时,会复制。

// Copy is made:
Employee frank = boss;

那么什么时候使用指针,何时使用引用?我发现一个好的做法是只在有意义的情况下使用指针null。如果某些内容不应为null,请将其作为参考。

答案 2 :(得分:2)

通常,您希望尽可能多地使用引用。原因是因为RAII。基本上,如果您使用RAII,这可以保证没有内存泄漏。

但是,当您使用的对象复制起来非常昂贵时,IMO应该使用指针。传递容器类型将导致容器的重复发生...不是一个好主意。

最好的方法是使用smart pointers ...基本上包含指针的引用并跟踪指针的引用数。这真是两全其美......廉价的初始化/复制和引用计数几乎可以消除内存泄漏。

答案 3 :(得分:2)

注意:我将使用“object”来引用对象和基本类型,例如int,float ......这些在C ++中是不一样的(但通常你可以忽略它)。

在创建从该范围控制的对象时使用值,并且当该范围结束时它应该死亡。另外,当您想要使用外部对象的副本时使用值,但您只想处理副本而不是真实对象。例如:

int myFunction(int external_value1, Object external_value2){
    ---
}

当你创建一个在创建范围结束时不应该死的Object时,请使用指针/引用(确保将指针传递给其他范围!),或者使用复制成本高的外部值时(像一个容器),或者你想直接在那个外部对象上操作而不是在它的副本上。这就是为什么函数的I / O参数通常是指针或引用的原因,因为您希望直接作用于外部对象(在函数范围之外定义)而不是本地副本。例如:

int myOtherFunction(int *external_value1, Object *external_value2{
    ---
}

在此示例中,如果对参数指向的值进行操作,则会严格影响:指针指向的值,从而更改函数作用域之外的变量。实际上是一个按值传递,但是你只复制指针,并使用它们来“攻击”外部值。

如其他帖子所述,参考文献只是指针的语法糖。一旦理解了指针,就可以理解参考文献;)。

答案 4 :(得分:1)

C ++ FAQ对这个具体问题有一个很好的答案:

http://www.parashift.com/c++-faq-lite/references.html#faq-8.6

答案 5 :(得分:1)

答案 6 :(得分:0)

两种不同的野兽:如果你通过指针分配,你最终会得到n对1的关系,你必须通过适当的资源管理来处理这种关系。这通常用Java来处理。

在你所谓的“参考对象”中,你会得到不同的对象(需要跟踪它们等)。