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

发布于 2024-10-14 21:20:32 字数 1147 浏览 5 评论 0 原文

在使用智能指针进行练习并了解它们如何通过 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

我不太明白。

In practicing with smart pointers and seeing how they can prevent memory leaks and aid memory management through RAII, I was doing the following:

#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;
}

Is there any way I could something similar to this (hopefully my aim comes across in the 'pseudo' code):

a = new int[50];

I can see why this won't work from the Boost shared_ptr.hpp file itself, but I don't understand why this will not work then:

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

It returned this error:

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

Which I don't exactly understand.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱她像谁 2024-10-21 21:20:32

首先,boost::detail 中的任何内容都是实现细节。除非您正在开发将成为 boost 本身一部分的代码,否则不要碰它。

其次,boost::shared_ptr 不能直接包装数组。这是因为 C++ 中的数组必须用 delete [] 删除,而 boost::shared_ptr 则用 delete 删除。使用 boost::shared_array 相反,或者可能是 boost::shared_ptrstd::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_arrayshared_ptr 。 >

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

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的旧值)被释放。

First, anything in boost::detail is an implementation detail. Don't touch it unless you're developing code that will be a part of boost itself.

Second, boost::shared_ptr is not directly capable of wrapping arrays. This is because arrays in C++ must be deleted with delete [], while boost::shared_ptr deletes with delete instead. Use boost::shared_array instead, or perhaps a boost::shared_ptr to a std::vector. If you really must use a shared_ptr with an array, you must create it using a custom deleter:

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

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

Please don't actually do this, however. Use a shared_array<int> or a shared_ptr<vector<int> >.

As for why you can't just do:

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

This is because it would be dangerous to make it too easy to make something a shared_ptr - remember, if you make something a shared_ptr twice, you'll end up double-freeing it. So shared_ptrs will only take raw pointers through their constructor. If you really want to overwrite a shared_ptr with a raw pointer, here's one way:

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

This creates a new pointer, then swaps it with a. The temporary smart pointer (with a's old value) is then freed.

卸妝后依然美 2024-10-21 21:20:32

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

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

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

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

You can't assign something allocated with new int[50] to a shared_ptr<int> unless you also supply a custom deleter that performs delete[] instead of delete.

enable_shared_from_this is designed to add the ability for class types to retrieve an owning shared pointer, you've just pulled something out of the detail namespace. This isn't designed to be used directly. It's designed to be used like this.

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

The simplest managing container for arrays would be std::vector<int>, not shared_ptr.

青萝楚歌 2024-10-21 21:20:32

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

至于您收到的特定错误,该错误通常意味着您尝试调用传入非 POD 参数的 varargs 函数。在本例中,这是因为 boost::shared_ptr 不是 POD 类型。我认为这与使用数组和原始指针无关;我认为你只是用错误的参数调用了错误的函数。您是想使用 boost::shared_from_this 吗?

For starters, the function you're calling is in the detail namespace, meaning that it's probably not meant to be invoked directly. That may have something to do with your problem.

As for the particular error you're getting, that error usually means that you tried to call a varargs function passing in a non-POD argument. In this case, that's because boost::shared_ptr<int> isn't a POD type. I think this has nothing to do with using arrays versus raw pointers; I think you're just calling the wrong function with the wrong arguments. Did you mean to use boost::shared_from_this?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文