提升智能指针和非POD类型(C ++)

时间:2011-01-29 11:00:35

标签: c++ memory pointers boost smart-pointers

在使用智能指针进行练习并了解如何通过RAII防止内存泄漏并帮助进行内存管理时,我正在执行以下操作:

#include <boost/shared_ptr.hpp>
#include <vector>

#include <iostream>

using std::cout;
using boost::shared_ptr;

class myobj {
    public:
    shared_ptr<int> a;
    myobj() {
        shared_ptr<int> b(new int[50]);
        a = b;
    }
    ~myobj() {}
};

typedef boost::shared_ptr<myobj> myobj_ptr;

int main() {
    for (unsigned int i=0; i < 5000000; i++) {
        myobj *foo = new myobj();
        myobj *bar = new myobj();
        myobj_ptr bar_ptr(bar);

        bar_ptr = myobj_ptr(foo);
        bar = foo;
    }
    return 0;
}

有什么方法可以解决类似的事情(希望我的目标在'伪'代码中出现):

a = new int[50];

我可以看到为什么这不会起作用Boost shared_ptr.hpp文件本身,但我不明白为什么这不起作用呢

shared_ptr<int> a;
int *b;
myobj() {
    b = new int[50];
    boost::detail::sp_enable_shared_from_this( a, b, b );
}

它返回了这个错误:

warning: cannot pass objects of non-POD type ‘class boost::shared_ptr<int>’ through ‘...’; call will abort at runtime

我不太清楚。

3 个答案:

答案 0 :(得分:3)

首先,boost::detail中的任何内容都是实现细节。除非您正在开发能够成为助推器本身的代码,否则请勿触摸它。

其次,boost::shared_ptr不能直接包装数组。这是因为必须使用delete []删除C ++中的数组,而使用boost::shared_ptr删除delete。请改为使用boost::shared_array,或boost::shared_ptr使用std::vector。如果您真的必须使用带有数组的shared_ptr,则必须使用自定义删除器创建它:

template <typename T>
struct array_deleter {
  void operator()(T *p) {
    delete [] p;
  }
};

// later...
boost::shared_ptr<int> p(new int[50], array_deleter<int>());

但请不要这样做。使用shared_array<int>shared_ptr<vector<int> >

至于为什么你不能这样做:

boost::shared_ptr<int> a;
// later
a = new int;

这是因为让一个shared_ptr变得太容易会很危险 - 记住,如果你做了两次shared_ptr的话,你最终会把它释放出来。所以shared_ptrs只会通过构造函数获取原始指针。如果你真的想用原始指针覆盖shared_ptr,可以采用以下方法:

a.swap(boost::shared_ptr<int>(new int));

这将创建一个新指针,然后将其与a交换。然后释放临时智能指针(具有a的旧值)。

答案 1 :(得分:2)

除非您还提供执行new int[50]而不是shared_ptr<int>的自定义删除工具,否则您无法将使用delete[]分配的内容分配给delete

enable_shared_from_this旨在为类类型添加检索拥有共享指针的功能,您只需从detail命名空间中提取内容。这不是为了直接使用而设计的。它被设计成像这样使用。

class myobj : public boost::enable_shared_from_this<myobj>
{ //...

数组最简单的管理容器是std::vector<int>,而不是shared_ptr

答案 2 :(得分:0)

对于初学者来说,您正在调用的函数位于detail命名空间中,这意味着它可能不是直接调用的。这可能与您的问题有关。

至于你得到的特定错误,该错误通常意味着你试图调用传递非POD参数的varargs函数。在这种情况下,那是因为boost::shared_ptr<int>不是POD类型。我认为这与使用数组与原始指针无关;我认为你只是用错误的参数调用错误的函数。您的意思是使用boost::shared_from_this吗?