我有 C#和 obj-c 的背景,所以RC / GC是我(仍然)对我持有的东西。当我开始更深入地学习 C ++ 时,我不禁想知道为什么我会使用普通指针,因为它们是 unmanaged 而不是其他替代解决方案?
shared_ptr 提供了一种很好的方式来存储引用,而不会丢失它们而不删除它们。我可以看到普通指针的实用方法,但它们似乎只是不好的做法。有人可以提出这些替代方案吗?
答案 0 :(得分:11)
当然,如果他们拥有指针,你会被鼓励使用共享和独特的ptr。但是,如果你只需要一个观察者,那么一个原始指针就可以了(指针对它指向的任何东西都不负责)。
std::uniqe_ptr
基本没有开销,std::shared_ptr
中有一些开销,因为它为你引用计数,但你很少需要在这里节省执行时间。
此外,如果您可以通过设计保证生命/所有权等级,则不需要“智能”指针;说一个树中的父节点比其子节点更长 - 尽管这与指针实际上是否拥有某些东西有点关系。
答案 1 :(得分:5)
问题恰恰相反:为什么要使用智能
指针?与C#(我认为Obj-C)不同,C ++广泛使用
使用值语义,这意味着除非一个对象有一个
应用程序特定的生命周期(在这种情况下,没有智能
指针适用),你通常会使用值语义,和
没有动态分配。有例外,但如果你做到了
在价值语义方面的一个思考点(例如
int
),定义适当的拷贝构造函数和赋值
必要时运营商,不动态分配
除非对象具有外部定义的生命周期,否则你将会这样做
发现你很少需要做更多的事情;一切都好
照顾好自己。使用智能指针非常重要
大多数编写良好的C ++中的异常。
答案 2 :(得分:5)
正如其他人提到的,在C ++中你必须考虑所有权。话虽这么说,我正在研究的3D联网多人FPS有一个名为“No new or delete”的官方规则。它仅使用共享和唯一指针来指定所有权,并使用.get()
从它们检索的原始指针(我们需要与C API进行交互)。性能影响不明显。我以此为例来说明由于游戏/模拟通常具有最严格的性能要求而导致的性能损失可以忽略不计。
这也大大减少了调试和追踪内存泄漏所花费的时间。从理论上讲,精心设计的应用程序永远不会遇到这些问题。然而,在现实生活中使用设计不当的截止日期,遗留系统或现有游戏引擎,它们是游戏等大型项目的必然性......除非你使用智能指针。如果您必须动态分配,没有足够的时间来设计/重写体系结构或调试与资源管理相关的问题,并且您希望尽快将其发布到现场,那么智能指针是可行的方式即使在大型游戏中也会有明显的性能成本。
答案 3 :(得分:2)
有时您需要与C API进行互操作,在这种情况下,您需要使用原始指针 至少代码的那些部分。
答案 4 :(得分:1)
在嵌入式系统中,指针通常用于访问特定地址的硬件芯片或存储器的寄存器。
由于硬件寄存器已经存在,因此无需动态分配它们。如果删除指针或更改其值,则不会发生任何内存泄漏。
与函数指针类似。函数不是动态分配的,它们具有“固定”地址。重新分配函数指针或删除函数指针不会导致内存泄漏。