Shared_ptr coexists with pointers

I have the following function

void a(shared_ptr<X> val) {...}

Sometimes I want to pass an object with a dedicated heap

shared_ptr<X> v(new X());
a(v);

In other cases, I want to pass an object allocated to the stack

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

What is the best way to force a function to accept smart pointers, but also allow smart pointers to reference the stack of selected objects?

Or should I go along the Java route and allocate everything from the heap?

+3
source share
7 answers

I just would like the function to accept the template parameter as follows:

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

then you can do like this:

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

func(v);  // works
func(&x); // also works

You can pass anything that has a pointer, such as an interface, for example, iterators:

std::vector<int>::iterator it = v.begin();
func(it); // still works :-)
+9

, , . , , , , , .

, -, , , . , , , .

+6

null_deleter shared_ptr.

, shared_ptr , .

struct null_deleter
{
  void operator() (void const*) const {};
};

:

Foo foo;
shared_ptr<Foo> pfoo(&foo, null_deleter());

, shared_ptr. , , , - .

:

shared_ptr<Foo> pfoo;

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

// Now pfoo points to freed data !
pfoo->doSomething(); // Undefined behavior
+5

( ). !

+3

, shared_ptr, , .

, , , - . shared_ptr , , . , , , . , , -, ( shared_ptr, ). , , , shared_ptr .

, , , , ...

void a( C & val ) // just pass by reference (or const reference)
{
    val.member = 10; // for example
}

shared_ptr<X> v(new X());
a(*v); // simply dereference the pointer to call the function

// verify that v holds an object if it isn't obvious from the context
if ( v ) a(*v);

class C
{
    C() { a(x); } // nothing fancy required to call the function
    X x;
};

, , a .

, ...

std::vector<int>::iterator it = v.begin();
a(*it); // also works
+3

, shoehorn shared_ptr, shared_ptr. , , shared_ptr, , "" , , shared_ptr, . , - , .

+2

shared_ptr : . . , .

ereOn, -, , . - , shared_ptr:

void a(X &val){
  a(shared_ptr<X>(&val, null_deleter()));
}

This, at least, saves the user a hacking problem. No matter how secure it is, it depends on semantics a(). If you take a pointer and store it in some kind of global / persistent object that will exist after the return a(), you still run the risk of undefined behavior. In this case, the only safe way to solve the problem is to create a copy:

void a(const X &val){
  a(shared_ptr<X>(new X(val));
}
+1
source

Source: https://habr.com/ru/post/1780883/


All Articles