Let's say that I have some arbitrary class, A:
class A {
//... stuff
};
I want to call into an external API that takes in a shared pointer to some type, like so (I cannot change this interface):
//...much later
void foo(std::shared_ptr<A> _a){
//operate on _a as a shared_ptr
}
However, in the (legacy) code I'm working with, the class A
instance I'm working with is allocated on the stack (which I cannot get around):
A a;
//...some stuff on a
//Now time to call foo
On top of this, an instance of class A is quite large, on the order of 1 GB per instance.
I know I could call
foo(std::make_shared<A> a);
but that would allocate memory for a copy of A, which I would really like to avoid.
Is there a way to hack together some call to std::make_shared
(possibly with move
semantics) so that I am not forced to allocate memory for another instance of class A?
I've tried something like this:
foo(std::make_shared<A>(std::move(a)));
But from what I can tell, a new instance of A
is still created.
#include <iostream>
#include <memory>
using namespace std;
class A{
public:
A(int _var=42) : var(_var){cout << "Default" << endl;}
A(const A& _rhs) : var(_rhs.var){cout << "Copy" << endl;}
A(A&& _rhs) : var(std::move(_rhs.var)){cout << "Move" << endl;}
int var;
};
void foo(std::shared_ptr<A> _a){
_a->var = 43;
cout << _a->var << endl;
}
int main() {
A a;
cout << a.var << endl;
foo(std::make_shared<A>(std::move(a)));
cout << a.var << endl;
a.var = 44;
foo(std::make_shared<A>(std::move(a)));
cout << a.var << endl;
return 0;
}
Default
42
Move
43
42
Move
43
44
This is possible with the shared_ptr
constructor that allows for an "empty instance with non-null stored pointer":
A x;
std::shared_ptr<A> i_dont_own(std::shared_ptr<A>(), &x);
(It's "overload (8)" on the cppreference documentation.)
If you know that shared pointer you pass to foo()
will not get stored, copied etc, ie will not outlive your object you can make std::shared_ptr
pointed to object on the stack with empty deleter:
void emptyDeleter( A * ) {}
A a;
foo( std::shared_ptr<A>( &a, emptyDeleter ) );
Again you need to make sure that shared pointer or it's copy will not outlive the object and well document this hack.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With