你啥时候想在 C++ 中使用指针和值?
Posted
技术标签:
【中文标题】你啥时候想在 C++ 中使用指针和值?【英文标题】:When do you want to use pointers vs values in C++?你什么时候想在 C++ 中使用指针和值? 【发布时间】:2010-12-06 12:28:48 【问题描述】:我来自 Java,正在尝试学习 C++。
据我所知,使用指针与 Java 中引用变量的工作方式非常相似,因为您将内存地址传递给值。所以我觉得我对他们有了很好的了解。我也明白这些变量是存储在堆上的。
但是,我发现还有另一种方法可以在 C++ 中声明变量,而无需 new 运算符/指针简单地执行以下操作:
Employee boss("Frank");
这将创建一个以“Frank”为参数的 Employee 值。这些变量存储在堆栈中。
所以,您有这两种非常不同的创建变量的方式,并且都有自己独特的行为(还有内存管理?)。
我的问题是,什么时候适合使用指针 VS 值?最佳做法是什么?我应该如何知道大多数时候我想以哪种方式声明我的变量?
【问题讨论】:
“参考”是 C++ 中的一个特定术语,所以我稍微编辑了您的问题以使用更正确的“值”。 @John Millikin,感谢您清理我的帖子,您的意图是正确的。我有时仍然会偶然发现 C++ 命名法。 我建议在学习 C++ 之前先忘掉 Java。它们是不同的,如果你试图在它们之间进行类比,你只会混淆你自己和我。 复制,无论如何:***.com/questions/1064325/…. @GMan,我对它们进行了比较,因为我发现指针类似于 Java 的参考变量。然后我说我理解 2 种 C++ 变量创建方法背后的行为,我想回答的唯一问题是何时适合使用特定的方法。 【参考方案1】:C++ 指针的操作与 Java 对象完全一样,因为它们可能无效 (NULL
) 并且传递给过程的成本很低。
C++ 引用是指针的薄包装。它们不应该是无效的,但在某些情况下可能是。例如,引用可能是从 NULL
指针创建的,或者它引用的内存可能会被删除。
在你给出的代码示例中:
Employee boss("Frank");
你正在使用一种叫做“价值”的东西。与指针和引用不同,值是它们所代表的对象,而不是间接。
我的问题是,什么时候合适 使用指针 VS [值]? 最佳做法是什么?应该怎样 我知道我想以什么方式声明 大部分时间都是我的变量?
C++ 没有垃圾收集,因此当变量的范围有限时使用值。例如,您可以在堆栈上分配它们,而不用担心内存,而不是用new
分配一个并用delete
解除分配过程中的每个变量。
【讨论】:
【参考方案2】:这里有两个不同的问题:创建对象和引用它们。
创作
创建对象的地方有两个:栈和堆。如果您使用您描述的语法:
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
有意义时才使用指针。如果某些内容不应该为空,请将其设为引用。
【讨论】:
【参考方案3】:通常,您希望尽可能多地使用参考文献。原因是因为RAII。基本上,如果您使用 RAII,这可以保证没有内存泄漏。
但是,当您使用的对象复制起来非常昂贵时,IMO 您应该使用指针。传递容器类型会导致容器重复...不是一个好主意。
最好的方法是使用smart pointers... 基本上是持有一个指针并跟踪指针的引用数量的引用。这确实是两全其美...廉价的初始化/复制和引用计数实际上消除了内存泄漏。
【讨论】:
【参考方案4】:注意:我将使用“object”来指代对象和原始类型,例如 int、float……这些在 C++ 中是不一样的(但通常你可以忽略它)。
在您创建从该范围控制的对象时使用值,并且在该范围结束时它应该死掉。此外,当您想使用外部对象的副本时使用 value,但您只想处理副本而不是真实对象。示例:
int myFunction(int external_value1, Object external_value2)
---
当你创建一个在创建范围结束时不应该死掉的对象时使用指针/引用(确保将指向它的指针传递到其他范围!),或者当使用复制成本高昂的外部值时(像一个容器),或者当你想直接操作那个外部对象而不是它的副本时。这就是为什么函数的 I/O 参数通常是指针或引用的原因,因为您希望直接作用于外部对象(在函数范围之外定义)而不是本地副本。示例:
int myOtherFunction(int *external_value1, Object *external_value2
---
在这个例子中,如果你对参数指向的值进行操作,你会影响到:那些指针指向的值,从而改变函数范围之外的变量。实际上是按值传递,但您只是复制指针,并使用它们“攻击”外部值。
正如其他帖子所述,引用只是指针的语法糖。一旦你理解了指针,你就理解了引用;)。
【讨论】:
【参考方案5】:C++ FAQ 对这个特定问题有很好的回答:
http://www.parashift.com/c++-faq-lite/references.html#faq-8.6
【讨论】:
不是真的;他在 Java 方面的背景引起了一些术语混乱。他不是在问指针与引用,而是指针与堆栈分配的值。【参考方案6】: When to use pointers and when not to? C++ References and Java References Switching from Java to C++ - What's the Easy Way? many more【讨论】:
【参考方案7】:两种不同的野兽:如果你通过指针分配,你最终会得到 n 对 1 的关系,你必须通过适当的资源管理来处理。这通常在 Java 中处理。
在所谓的“参考对象”中,您会得到不同的对象(需要跟踪等)。
【讨论】:
你怎么称呼“参考对象”,所以我知道正确的术语吗?我不知道所以我只是编造了一些东西。以上是关于你啥时候想在 C++ 中使用指针和值?的主要内容,如果未能解决你的问题,请参考以下文章