shared_ptr与指针共存

jam*_*o00 3 c++ pointers smart-pointers

我有如下功能

void a(shared_ptr<X> val) {...}
Run Code Online (Sandbox Code Playgroud)

有时,我想传入一个堆分配的对象

shared_ptr<X> v(new X());
a(v);
Run Code Online (Sandbox Code Playgroud)

其他时候,我想传入一个堆栈分配的对象

class C
{
    //doesn't work properly b/c when the shared_ptr dies it will try to delete x...
    C() { a(shared_ptr<X>(&x)); } 
    X x;
};
Run Code Online (Sandbox Code Playgroud)

使函数接受智能指针的最佳方法是什么,还要让智能指针引用堆栈分配的对象?

或者我应该去Java路由并从堆中分配所有内容?

Eva*_*ran 9

我只是让函数采用这样的模板参数:

template<class P>
void func(P ptr) {
     // use ptr like a pointer as usual
     // for example
     *ptr = 10;
}
Run Code Online (Sandbox Code Playgroud)

然后你可以这样做:

shared_ptr<int> v(new int);
int x;

func(v);  // works
func(&x); // also works
Run Code Online (Sandbox Code Playgroud)

您可以传递任何具有类似接口的指针,例如,迭代器:

std::vector<int>::iterator it = v.begin();
func(it); // still works :-)
Run Code Online (Sandbox Code Playgroud)


tyr*_*731 6

如果您正在使用堆栈分配的内存,则不应使用智能指针period.Boost智能指针是围绕这样的概念设计的,即在一些范围内需要删除堆分配的内存,因此没有明显的概念告诉这样的指针不释放某些内存.

您可以将删除函数指定为智能指针的第二个参数,并使该函数不删除内存,但是读取代码的任何人都将不清楚传递给此函数的内存的生命周期.因此,如果您需要使用智能指针,则应该在堆上分配传递给它们的任何内存.


ere*_*eOn 5

你可以使用null_deleter和仍然使用shared_ptr.

这样shared_ptr,在销毁时不会删除关联的指针.

struct null_deleter
{
  void operator() (void const*) const {};
};
Run Code Online (Sandbox Code Playgroud)

然后你可以这样使用它:

Foo foo;
shared_ptr<Foo> pfoo(&foo, null_deleter());
Run Code Online (Sandbox Code Playgroud)

然而,这并不完全shared_ptr是为了什么.如果你在程序中经常使用这个hack,你可能也想重新考虑你的设计,因为它可能表明出现了问题.

考虑以下情况:

shared_ptr<Foo> pfoo;

{
  Foo foo;
  pfoo.reset(&foo, null_deleter());
} // foo gets destroyed

// Now pfoo points to freed data !
pfoo->doSomething(); // Undefined behavior
Run Code Online (Sandbox Code Playgroud)