Скажем, что у меня есть некоторый произвольный класс, A:
class A {
//... stuff
};
Я хочу вызвать внешний API, который использует общий указатель на некоторый тип, например (Я не могу изменить этот интерфейс):
//...much later
void foo(std::shared_ptr<A> _a){
//operate on _a as a shared_ptr
}
Однако в (устаревшем) коде, с которым я работаю, экземпляр класса A
, с которым я работаю, выделяется в стеке (, который я не могу обойти):
A a;
//...some stuff on a
//Now time to call foo
Кроме того, экземпляр класса A довольно велик, порядка 1 ГБ на каждый экземпляр.
Я знаю, что могу позвонить
foo(std::make_shared<A> a);
но это выделило бы память для копии A, чего я бы очень хотел избежать.
Вопрос
Есть ли способ взломать некоторый вызов std::make_shared
(возможно с семантикой move
), так что я не вынужден выделять память для другого экземпляра класса A?
Я пробовал что-то вроде этого:
foo(std::make_shared<A>(std::move(a)));
Но из того, что я могу сказать, новый экземпляр A
все еще создан.
Пример кода
#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;
}
Вывод:
По умолчанию
42
Перемещение
43
42
Перемещение
43
44