Now that smart pointers exist, is it deprecated style to use C type pointers?
Possible Duplicate:
Which kind of pointer do I use when?
有很多优点支持C++ 11的智能指针:它们更安全,它们的功能和范围更为隐蔽。
是"经典"C型指针吗?
1 2 3
| class C{};
C c;
C* c_p = &c; |
现在过时了吗?他们甚至被否决了吗?或者是否存在C指针仍然有意义的用例?
编辑:带有智能指针的代码段:
1 2 3
| class C{};
C c;
std::shared_ptr<C> c_p(new C()); |
编辑:感谢您指出副本。从Xeo的回答来看:
Use dumb pointers (raw pointers) or references for non-owning references to resources and when >you know that the resource will outlive the referencing object / scope. Prefer references and >use raw pointers when you need either nullability or resettability.
如果只有这些,我接受这个问题已经解决了。
- 使用EDCOX1×0操作符的一个例子可能更好地说明智能指针的优点;
- "既然存在智能指针"?智能指针不是新的。双关语
- @我承认我的问题迟了几年。但还是…
有一些原始指针有意义的用例。
现代代码中的原始指针是"非拥有"指针。这意味着代码不应该做任何需要或取得指向对象所有权的事情。例如,它不应该是deleted,用于构造拥有的智能指针,或者保存在当前上下文之外。
- 虽然我承认我从未使用过,但现在可以由std::reference_wrapper来填补不拥有、可重新分配的引用的角色。
- @巴尼斯53:这是原始指针不应该做的……他们应该怎么做?
- @史蒂芬,你没有得到答案,还是这是个玩笑?他不是建议你不要用原始指针做某些事情,而是建议你在某些情况下使用原始指针,即当你不使用指向对象做某些事情时。
- @列表中的steffen是不应该用非拥有指针来完成的事情,而不是不应该用原始指针来完成的事情。对于原始指针,您应该将其用作非拥有指针。(对于非拥有指针,您应该做的事情是针对nullptr进行测试,并将其取消为使用指向对象)
- "针对nullptr的测试":我可以使用智能指针来避免这种情况。Derefernce it:这是我对任何指针都会做的。换句话说:在哪些情况下,使用原始指针更好?
- 斯特芬,标准的智能指针可以是空的,所以你仍然测试它们。当你想要一个指针时,最好使用一个原始指针,但是你不想用它传递所有权。也就是说,当你需要一个非拥有指针。
- @巴恩斯53:对不起,请坚持。当我想要一个非拥有指针时,我将使用一个EDCOX1 1。或不是?
- @steffen weak_ptr是仅共享_ptr的非拥有对应项,使用原始指针可以被视为唯一_ptr的非拥有对应项。
- 好的,谢谢您的耐心等待;)
绝对不是。智能指针用于特殊情况,而不是用于一般用途。根据应用程序和编程风格,大多数指针仍然是原始指针;在某些情况下,实际上一点也不聪明。
- 我尊重地不同意。对于需要询问的人来说,大多数指针可能都是智能指针。(剩下的几个可以看作是随机访问迭代器。)
- 我会说"默认"指针现在是"std::unique"指针。大多数情况下,指针表示拥有的数据
- 如果有人需要问,那么标准的智能指针只会导致更多的问题。实际上,在大多数应用程序中,大多数指针都是用于导航的,不应该是智能指针。它们不能是unique_ptr,因为同一对象有许多指针,也不能是shared_ptr,因为会有循环。大多数对象的生存期由应用程序决定;否则,它们可能不应该动态分配以开始。这意味着聪明的指针无论如何也做不到正确的事情。
- @你一定有一个不寻常的申请。为什么要动态分配拥有的数据?
- 假设你正在制作一个游戏,你动态地创建一个"怪物"对象,你可能希望它被怪物控制器"拥有"。像产卵器一样,它可能需要一个弱指针,这样它就可以跟踪它已经产卵了多少仍然活着的怪物,所以它知道是否应该制造更多的怪物。我承认这是人为的例子,但并不牵强。
- @如果你在做一个游戏(你不必担心事务完整性之类的问题),那么一个Monster类型的对象几乎肯定会在某个时刻做一个delete this,比如当它的点击率降到某个水平以下时。这里没有通常聪明的指点。
- @jameskanze,但是类似于怪物的"法术效果"的东西,属于怪物对象,因此应该通过智能指针来完成。是的,您可以使用原始指针,但是如果您要坚持过时的方法,有什么希望呢?
- @怪物拥有的怪物的东西可能最好是通过聚合来处理,而不是通过指针。(当然,如果它们是多态的,那么就需要动态分配,在这种情况下,std::unique_ptr可能是可行的方法。)
- @詹姆斯:"…大多数指针都是用于导航的……"我已经准备好了,所以说:"剩下的几个指针可以被视为随机访问迭代器。"这不是大多数用户(特别是新手)在考虑指针时所想的。
- @jameskanze:大多数动态分配的对象将存储在某种容器中,对于那些容器来说,智能指针是完美的选择。
- 那就更好了,更好。通过避免原始指针(您可能不总是能够做到这一点),您可以避免让自己担心这种低级别的内存管理。处理内存的自动化程度越高,代码的维护就越容易。
- @我不记得上次我有一个容器拥有任何指向对象。只有在存在某种形式的多态性时,这才有意义,多态对象通常是实体对象,具有定义的生存期,独立于容器。
- @Jameskanze:那么也许我或者你有一个奇怪的应用领域。在过去的十年或二十年中,我看到的许多代码创建了多态对象,然后需要将其存储在某个地方。
- @Jameskanze:"在学习者真正理解原始指针以及如何使用它们之前,不应该将它们介绍给智能指针……"奇怪的是,我完全同意这一点。但是,我认为用户不必使用原始指针来理解智能指针的有用性。多年来,我一直教C++的学生认识Java,我只解释了手工资源管理的危险,这足以让他们欣然接受智能指针。
- "…这只在特殊情况下使用"好吧,如果你能很好地看到这个评论讨论的开始,你会发现我从一开始就不同意这个前提。这违背了我的经验。
- @我处理过的大多数多态对象都是实体对象,它们的生存期由程序规范决定,而不是由它们是否恰好在某个容器中决定。(此类对象的析构函数可将其从多个不同的容器中移除。但这是毁灭的触发触发,而不是反之亦然。
- JAMESKANZE我对你的观点感到困惑。是的,对于一个新的C++对象和指针的概念,这四种类型可能有点混乱。但是一个更有经验的开发人员应该知道并理解细微的差异,并且知道何时使用每种类型。然而,为了回到最初的辩论中,你关于人们在默认情况下应该使用原始指针的陈述至少是有问题的。如果有些人需要问他们需要什么类型,我会将他们推向唯一的ptr,除非有其他信息会改变这一点,例如需要共享访问
- @在大多数需要指针的情况下,shman unique_ptr不起作用。shared_ptr也没有(因为大多数需要指针的情况都涉及循环)。
- @Jameskanze(&176;□&176;)
不,原始指针没有过时。除非必要,否则通常不鼓励使用它们。更不鼓励通过原始指针维护对象的所有权,因为您必须记住delete,这在出现异常时可能很难做到。
原始指针比智能指针更有效,因此在代码的某些性能敏感的部分使用它们是有意义的。在一些领域,比如线性代数中,指针算法是有用的,您可以在那里使用原始指针[1],或者在原始指针之上构建新的抽象,可能与智能指针结合使用,而不是只使用智能指针。
[1]例如,用于定义子矩阵的视图