java 智能指针_什么是智能指针,何时应使用?

什么是智能指针,何时应使用?

#1楼

在计算机科学中,智能指针是一种抽象数据类型,它在提供其他功能(例如自动垃圾收集或边界检查)的同时模拟指针。 这些附加功能旨在减少因滥用指针而导致的错误,同时保持效率。 智能指针通常会跟踪指向它们的对象,以进行内存管理。 指针的滥用是错误的主要来源:必须由使用指针编写的程序执行常量分配,释放和引用,这很可能会发生一些内存泄漏。 智能指针试图通过使资源自动分配来防止内存泄漏:当指向某个对象的指针(或一系列指针中的最后一个)被破坏时,例如,由于超出范围,指向的对象也将被破坏。

#2楼

智能指针就像常规的(类型化的)指针一样,如“ char *”,除了当指针本身超出范围时,它所指向的内容也会被删除。 您可以像使用常规指针一样使用“->”来使用它,但是如果您需要一个实际的数据指针,则不需要。 为此,您可以使用“&* ptr”。

它对:

必须分配给new的对象,但您希望拥有与该堆栈上的对象相同的生存期。 如果将对象分配给智能指针,则在程序退出该功能/块时将删除它们。

类的数据成员,以便在删除对象时也删除所有拥有的数据,而在析构函数中没有任何特殊代码(您需要确保析构函数是虚拟的,这几乎总是一件好事) 。

你可能不希望使用智能指针时:

...指针实际上不应该拥有数据...,即,当您仅使用数据时,但是您希望它在引用它的函数中存活下来。

...智能指针本身不会在某个时候被破坏。 您不希望它位于永不被破坏的内存中(例如,在动态分配但不会被明确删除的对象中)。

...两个智能指针可能指向同一数据。 (但是,还有更聪明的指针可以处理此问题……这称为引用计数 。)

也可以看看:

#3楼

大多数类型的智能指针都会为您处理指向对象的处理。 这非常方便,因为您不必再​​考虑手动处理对象。

最常用的智能指针是std::tr1::shared_ptr (或boost::shared_ptr ),以及std::auto_ptr 。 我建议定期使用shared_ptr 。

shared_ptr非常通用,可以处理各种处置方案,包括需要“跨越DLL边界传递对象”的情况(如果在代码和DLL之间使用不同的libc则通常是噩梦)。

#4楼

智能指针是一种类似指针的类型,具有一些其他功能,例如自动内存释放,引用计数等。

一种简单的智能指针类型是std::auto_ptr (C ++标准的20.4.5章),它允许在超出范围时自动释放内存,并且比引发异常时的简单指针使用更可靠,尽管这种情况较少灵活。

另一个方便的类型是boost::shared_ptr ,它实现引用计数并在没有剩余对对象的引用时自动释放内存。 这有助于避免内存泄漏,并且易于使用来实现RAII 。

防止异常

持有人,(请注意, std :: auto_ptr是此类智能指针的实现)

资源获取即初始化 (在C ++中经常用于异常安全的资源管理)

持有人限制

并发计数器访问

销毁和重新分配

#5楼

更新

这个答案很旧,因此描述了当时的“好”,这是Boost库提供的智能指针。 从C ++ 11开始,标准库提供了足够的智能指针类型,因此您应该赞成使用std::unique_ptr , std::shared_ptr和std::weak_ptr 。

还有std::auto_ptr 。 它非常类似于作用域指针,不同之处在于它还具有“特殊”危险功能,可被复制-还会意外地转移所有权。

它在C ++ 11中已弃用,在C ++ 17中已删除 ,因此您不应该使用它。

std::auto_ptr p1 (new MyObject());

std::auto_ptr p2 = p1; // Copy and transfer ownership.

// p1 gets set to empty!

p2->DoSomething(); // Works.

p1->DoSomething(); // Oh oh. Hopefully raises some NULL pointer exception.

老答案

智能指针是包装“原始”(或“裸露”)C ++指针的类,用于管理所指向对象的生命周期。 没有单一的智能指针类型,但是它们都尝试以一种实用的方式抽象一个原始指针。

智能指针应优于原始指针。 如果您觉得需要使用指针(首先考虑是否确实需要使用指针),则通常希望使用智能指针,因为这可以减轻原始指针的许多问题,主要是忘记删除对象和泄漏内存。

使用原始指针,程序员必须在不再有用时显式销毁该对象。

// Need to create the object to achieve some goal

MyObject* ptr = new MyObject();

ptr->DoSomething(); // Use the object in some way

delete ptr; // Destroy the object. Done with it.

// Wait, what if DoSomething() raises an exception...?

通过比较,智能指针定义了有关销毁对象的时间的策略。 您仍然必须创建对象,但是不必担心销毁它。

SomeSmartPtr ptr(new MyObject());

ptr->DoSomething(); // Use the object in some way.

// Destruction of the object happens, depending

// on the policy the smart pointer class uses.

// Destruction would happen even if DoSomething()

// raises an exception

void f()

{

{

std::unique_ptr ptr(new MyObject());

ptr->DoSomethingUseful();

} // ptr goes out of scope --

// the MyObject is automatically destroyed.

// ptr->Oops(); // Compile error: "ptr" not defined

// since it is no longer in scope.

}

请注意,无法复制std::unique_ptr实例。 这样可以防止多次(不正确)删除指针。 但是,您可以将对其的引用传递给您调用的其他函数。

如果要将对象的生存期绑定到特定代码块,或者将其作为成员数据嵌入另一个对象的生存std::unique_ptr则std::unique_ptr很有用。 该对象将一直存在,直到退出包含代码的块,或者直到包含对象本身被销毁为止。

更复杂的智能指针策略涉及对指针进行引用计数。 这确实允许复制指针。 当该对象的最后一个“引用”被销毁时,该对象将被删除。 该策略由boost::shared_ptr和std::shared_ptr 。

void f()

{

typedef std::shared_ptr MyObjectPtr; // nice short alias

MyObjectPtr p1; // Empty

{

MyObjectPtr p2(new MyObject());

// There is now one "reference" to the created object

p1 = p2; // Copy the pointer.

// There are now two references to the object.

} // p2 is destroyed, leaving one reference to the object.

} // p1 is destroyed, leaving a reference count of zero.

// The object is deleted.

当对象的生存期非常复杂,并且不直接与代码的特定部分或另一个对象绑定时,引用计数的指针非常有用。

引用计数的指针有一个缺点-可能创建悬挂的引用:

// Create the smart pointer on the heap

MyObjectPtr* pp = new MyObjectPtr(new MyObject())

// Hmm, we forgot to destroy the smart pointer,

// because of that, the object is never destroyed!

另一种可能性是创建循环引用:

struct Owner {

std::shared_ptr other;

};

std::shared_ptr p1 (new Owner());

std::shared_ptr p2 (new Owner());

p1->other = p2; // p1 references p2

p2->other = p1; // p2 references p1

// Oops, the reference count of of p1 and p2 never goes to zero!

// The objects are never destroyed!

要变通解决此问题,Boost和C ++ 11都定义了weak_ptr来定义对shared_ptr的弱(未计数)引用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值