使用智能指针作为编程标准吗?

| 我越来越多地听到,尽管我实现了有效的内存泄漏系统,但我应该使用智能指针而不是裸指针。 请问使用智能指针的正确编程方法是什么?即使我检查分配的内存块上的内存泄漏,也应该真正使用它们吗?还取决于我吗?如果我不使用它们,可以认为这是编程上的弱点吗? 如果强烈建议使用智能指针(例如std :: auto_ptr),我应该使用它们而不是每个裸指针吗?     
已邀请:
您应该使用RAII处理所有资源分配。 智能指针只是该规则的一种常见特殊情况。 而且智能指针不只是
shared_ptr
。有具有不同所有权语义的不同智能指针。使用适合您需求的那一种。 (主要的是
scoped_ptr
shared_ptr
weak_ptr
auto_ptr
/
unique_ptr
(如果可用,最好选择后者)。根据编译器的不同,它们可能在标准库中作为TR1的一部分提供,或者根本不提供,在这种情况下,您可以可以通过Boost库获取它们。 是的,您绝对应该使用这些。它不会花费您任何钱(如果做得正确,您将失去零性能),并且会收获很多(内存和其他资源会自动释放,您不必记住手动处理它,而使用该资源的代码变得更短,更简洁) 请注意,并非每种指针用法都代表某种资源所有权,因此并非所有原始指针用法都是错误的。如果您只需要指向别人拥有的对象,则原始指针非常适合。但是,如果您拥有该对象,则应该通过赋予类本身的RAII语义或将其包装在智能指针中来获得对它的适当所有权。     
您不能只为每个原始指针盲目地替换ѭ6。特别是,“ 4”是在转让时转移所有权,这对某些用途很有用,但对于其他用途则绝对不是。 确实有原因,有多种智能指针(例如,shared_ptr,weak_ptr,auto_ptr / unique_ptr等),每种都有不同的目的。 \“ raw \”指针的主要缺点是它具有许多不同的用途(并且具有通用性,主要是因为它几乎或根本不协助任何一种目的)。智能指针倾向于更加专业化,这意味着它们可以更好地做好一件事情,但是这也意味着您必须为工作选择合适的指针,否则最终将导致完全错误的事情。     
智能指针允许自动定义它所指对象的生命周期。这是要理解的主要内容。 因此,不,您不应该在所有地方都使用智能指针,仅当您想要使对象的生命周期自动化时,而不是例如让一个对象从出生到死亡来管理这些对象时,才应该使用智能指针。就像任何工具一样:它可以解决特定类型的问题,而不是全部问题。 对于每个对象,您应该考虑其将要经历的生命周期,然后选择最简单,正确且有效的解决方案之一。有时它将是shared_ptr,因为您希望该对象由多个组件使用,并且一旦不再使用将被自动销毁。有时您仅在当前范围/父对象中需要该对象,因此scoped_ptr可能更合适。有时您只需要一个实例的所有者,因此unique_ptr是合适的。也许您会发现一些案例,在这些案例中您知道一种可以定义/自动执行对象生命周期的算法,因此您将为其编写自己的智能指针。 例如相反的情况,使用池禁止您使用smart_ptr。在这种特殊情况下(但在嵌入式软件中很常见),裸露的指针可能是一个更受欢迎的简单有效的解决方案。 请参阅此答案(来自我)以获取更多说明:https://softwareengineering.stackexchange.com/questions/57581/in-c-is-it-a-reflection-of-poor-software-design-if-objects-are -deleted-manuall / 57611#57611     
即使我检查分配的内存块上的内存泄漏,也应该真正使用它们吗? 是 智能指针的全部目的是,它可以帮助您实现RAII(SBRM),它基本上可以让资源本身承担其重新分配的责任,并且资源不必依赖您明确记住要对其进行分配。 如果我不使用它们,可以认为这是编程上的弱点吗? 没有, 如果您不使用智能指针(RAII),则由您自己来显式管理资源不是一个弱点,而是一个麻烦或不必要的麻烦。实施RAII的智能指针的目的是提供一种高效且无忧的资源处理方式,如果您不使用它,就不会使用它。强烈建议将其纯粹用于其提供的众多优势。 如果强烈建议使用智能指针(例如std :: auto_ptr),我应该使用它们而不是每个裸指针吗? 是 您应该尽可能使用智能指针,因为使用它们没有任何缺点,而使用它们则有很多优点。 不要使用
auto_ptr
,因为它已经过时了!!您可以根据需要使用其他各种智能指针。您可以参考上面的链接以了解有关它们的更多信息。     
这是一个棘手的问题,目前存在一种 在任何地方使用智能指针都不会使事情变得容易。聪明 指针可以在某些情况下提供帮助,但是您当然不能仅仅 随处使用它们,无需思考。有很多不同的类型 的智能指针,您必须考虑哪种指针合适 在每种情况下即使如此,大多数指针(至少在典型情况下 我曾经工作过的域中的应用程序)应该是原始指针。 无论采用哪种方法,都有几点值得一提: 除非必须,否则不要使用动态分配。在许多 应用程序,唯一需要动态分配的内容 是具有特定寿命的对象,由应用程序确定 逻辑。不要对具有值语义的对象使用动态分配。 关于实体对象,那些在 应用程序领域:应根据这些内容创建和销毁它们 程序逻辑。不管是否有指向 他们与否。如果他们的销毁造成了问题,那么您有一个 您程序逻辑中某处的错误(无法正确处理事件, 等),并且使用智能指针不会改变任何内容。 实体对象的典型示例可能是 服务器,是在客户端连接时创建的,而在 客户端断开连接。在许多情况下,最合适的管理 将是
delete this
,因为它将是连接 断开连接事件。 (持有指向此类对象的指针的对象 将必须向其注册,以便被告知 破坏。但是,此类指针仅用于导航,不应 成为聪明的指针。) 人们在尝试使用智能指针时通常会找到的内容 到处都是内存泄漏;典型的参考计数器不 处理周期,当然,典型的应用程序充满周期:
Connection
将指向与其相连的
Client
,并且
Client
将包含连接的
Connection
列表。 如果智能指针是
boost::shared_ptr
, 指针悬空的风险:创建两个指针远非易事
boost::shared_ptr
到相同的地址(这导致两个计数器 供参考)。     
如果强烈建议使用智能指针(例如std :: auto_ptr),我应该使用它们而不是每个裸指针吗? 我认为,是的,您应该为自己拥有的每个指针使用它。 这是我对C ++中的资源管理的想法(随意不同意): 良好的资源管理需要考虑所有权。 资源应由对象管理(RAII)。 通常,单一所有权优先于共享所有权。 理想情况下,创建者还是对象的所有者。 (但是,在某些情况下,所有权转移是有序的。) 这导致以下做法: 将ѭ16作为本地变量和成员变量的默认选择。请记住,对成员变量使用
scoped_ptr
将使您的类不可复制。如果您不希望这样做,请参阅下一点。 使用ѭ14表示容器或启用共享所有权:
// Container of MyClass* pointers:
typedef boost::shared_ptr<MyClass> MyClassPtr;
std::vector<MyClassPtr> vec;
std::auto_ptr
(C ++ 03)可用于所有权转让。例如,作为工厂或克隆方法的返回值:
// Factory method returns auto_ptr
std::auto_ptr<Button> button = Button::Create(...);
// Clone method returns auto_ptr
std::auto_ptr<MyClass> copy = obj->clone();
// Use release() to transfer the ownership to a scoped_ptr or shared_ptr
boost::scoped_ptr<MyClass> copy(obj->clone().release());
如果需要存储您不拥有的指针,则可以使用原始指针:
this->parent = inParentObject;
在某些情况下,需要ѭ30。请参阅文档以获取更多信息。     
通常,您应该更喜欢智能指针,但是有两个例外。 如果您需要重铸指针,例如提供
const
版本,则使用智能指针几乎变得不可能。 智能指针用于控制对象的生存期。通常,当您传递指向函数的指针时,该函数不会影响生存期;该函数不尝试删除该对象,并且不存储指针的副本。在函数返回之前,调用代码无法删除对象。在那种情况下,完全可以接受一个哑指针。     
是。假设您可以使用C ++ 0x,请使用
unique_ptr
shared_ptr
(视情况而定)将
new
的所有原始指针包装起来。在
make_shared
的帮助下,
shared_ptr
表现出色。如果您不需要参考计数,
unique_ptr
将为您带来更好的性能。它们在集合和其他以“ 4”为哑指针的情况下均能正常工作。     
在任何地方使用智能指针(shared_ptr或其他)都是个坏主意。最好使用shared_ptr来管理对象/资源的生命周期,但是将它们作为参数传递给函数等不是一个好主意。这增加了循环引用和其他极难跟踪的错误的可能性(个人经验:如果每个函数调用都更改了引用计数,请尝试找出谁不应该占用200万行代码中的资源-您最终会认为从事此类工作的人是m *** ns。最好传递原始指针或引用。 与惰性实例化结合使用时,情况甚至更糟。 我建议开发人员应该知道他们编写的对象的生命周期,并使用shared_ptr来控制该对象(RAII),但不要在此范围之外扩展shared_ptr的使用。     

要回复问题请先登录注册