删除指向不完全类型和智能指针的指针 [英] Deletion of pointer to incomplete type and smart pointers

查看:425
本文介绍了删除指向不完全类型和智能指针的指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试将 auto_ptr 用于使用forward-declaration声明的类型时,如下所示:

  class A; 
...
std :: auto_ptr< A>一个;

A 的析构函数未调用显然,因为 auto_ptr internal delete 的底层指针和一个不完整类型的析构函数不能被调用)。



但是,同样的代码工作正常,当使用 std :: shared_ptr 而不是 std :: auto_ptr

$ <$ p $ <$>可以用不完整的类型声明,是的。



在初始化或重置 shared_ptr 时,类型不需要完成。指向一个新的对象,它创建一个删除者,可以用来销毁对象。例如,请考虑以下内容:

  //其中A不完整的地方:
std :: shared_ptr< class A> ; p;

//定义A
类A {/ * ... * /};

p.reset(new A());

当您调用 reset $ c> A 已完成,因为您正在使用 new 创建它的实例。 reset 函数在内部创建和存储一个删除器,将用于使用 delete 销毁对象。因为 A 在这里完成, delete 会做正确的事。



通过这样做, shared_ptr 不需要 A > shared_ptr< A> ;它只需要调用采用裸指针的 shared_ptr 构造函数时或当调用<$时, A c $ c> reset 使用原始指针。



请注意,如果 A 不是完成, , shared_ptr 将不会做正确的事情,行为是未定义的(这在 boost :: shared_ptr 的文档,这可能是学习如何使用的最佳资源 shared_ptr 您正在使用(Boost,TR1,C ++ 0x等)的 shared_ptr )。



但是,只要您始终遵循 shared_ptr 的最佳用法 - 总是使用调用 new 的指针直接初始化和重置 shared_ptr - 您不必



此功能不是免费的: shared_ptr 必须创建并存储一个指针删除函子;通常这是通过将删除程序存储为存储强和弱引用计数的块的一部分或通过将指针作为指向删除程序的块的一部分来完成的(因为您可以提供自己的删除程序)。



auto_ptr (和 unique_ptr )开销:对它的操作应该像使用哑指针一样有效。因此, auto_ptr 没有此功能。


When trying to use an auto_ptr with a type that was declared with forward-declaration, like this:

class A;
...
std::auto_ptr<A> a;

the destructor of A is not called (apparently, because auto_ptr internally deletes the underlying pointer and the destructor for an incomplete type cannot be called).

However, the same code works fine and the destructor is called when using std::shared_ptr instead of std::auto_ptr. How can that be explained?

解决方案

A shared_ptr can be declared with an incomplete type, yes. The type does not need to be complete until you initialize or reset it.

When you initialize or reset a shared_ptr to point to a new object, it creates a "deleter" that can be used to destroy the object. For example, consider the following:

// somewhere where A is incomplete:
std::shared_ptr<class A> p;

// define A
class A { /* ... */ };

p.reset(new A());

When you call reset, A is complete because you're creating an instance of it using new. The reset function creates and stores internally a deleter that will be used to destroy the object using delete. Because A is complete here, that delete will do the right thing.

By doing this, shared_ptr does not require that A be complete when the shared_ptr<A> is declared; it only requires that A is complete when the shared_ptr constructor that takes a raw pointer is invoked or when you call reset with a raw pointer.

Note that if A is not complete when you do one of those two things, shared_ptr won't do the right thing and the behavior is undefined (this is explained in the documentation for boost::shared_ptr, which is probably the best resource for learning how to use shared_ptr correctly, regardless which version of shared_ptr you are using (Boost, TR1, C++0x, etc.)).

However, as long as you always follow the best usage practices for shared_ptr--notably, if you always initialize and reset a shared_ptr directly with a pointer resulting from a call to new--you won't have to worry about violating this rule.

This functionality isn't free: shared_ptr has to create and store a pointer to the deleter functor; typically this is done by storing the deleter as part of the block that stores the strong and weak reference counts or by having a pointer as part of that block that points to the deleter (since you can provide your own deleter).

auto_ptr (and unique_ptr too) is designed to be free of any overhead: operations on it are supposed to be just as efficient as using a dumb pointer. Thus, auto_ptr doesn't have this functionality.

这篇关于删除指向不完全类型和智能指针的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆