Ich habe einige Legacy-Ära Code bei der Arbeit, die in einem Doppel-Zeiger und vergibt Speicher zu ihm. Ein verkürztes Beispiel dafür wäre etwa so aussehen:Verwenden von freigegebenen Zeigern mit Speicher in einer anderen Funktion
struct LegacyObj
{
int a;
double b;
};
void LegacyAllocator(LegacyObj** ppObj)
{
*ppObj = (LegacyObj*)malloc(sizeof(LegacyObj));
}
void LegacyDeleter(LegacyObj** ppObj)
{
free(*ppObj);
}
Die tatsächliche LegacyAllocator Funktion ist ~ 100 Zeilen und Mischungen Lesen aus Dateien mit einer verketteten Liste von LegacyObj Zeiger zu schaffen, und ist nicht etwas, was ich in der Lage sein würde um mit dem Umschreiben gerade fertig zu werden. Ich möchte jedoch die Verwendung dieser Funktion ein wenig sicherer machen und Speicherlecks vermeiden, die von Ausnahmen & TC auftreten können. Die erste Lösung, die ich mir ausgedacht hatte, war, sie in eine Klasse zu packen und die alten Funktionen im ctor/dtor aufzurufen.
class RAIIWrapper
{
public:
RAIIWrapper()
:obj{nullptr}
{
::LegacyAllocator(&obj);
}
RAIIWrapper(RAIIWrapper&& that)
: obj{ that.obj}
{
that.obj = nullptr;
}
RAIIWrapper& operator=(RAIIWrapper&& that)
{
RAIIWrapper copy{std::move(that)};
std::swap(obj, copy.obj);
return *this;
}
~RAIIWrapper()
{
::LegacyDeleter(&obj);
}
private:
LegacyObj* obj;
};
Aber ich bin neugierig - ist es eine Möglichkeit, diese std::shared_ptr
oder std::unique_ptr
mit zu tun? Ich war nicht in der Lage, eine Lösung zu finden, ohne den Originalzeiger an LegacyAllocator übergeben zu müssen.
'unique_ptr' und' shared_ptr' nehmen nicht Verteilern, sie nur nehmen Löscher. Sie würden den Zeiger selbst mit 'LegacyAllocator (& obj)' belegen und einen Deletier-Funktor für das 'unique_ptr' /' shared_ptr' erstellen, der 'LegacyDeleter (& p)' in seinem 'operator()' – David