Ich arbeite in einem Projekt mit einer großen Legacy-Code-Basis und habe versucht, Teile davon neu zu gestalten, um weg von altem C-Style-Code zu kommen.Warum werden meine Ergebnisdaten als void * zurückgegeben?
Ich bin auf ein Problem gestoßen und habe ein kurzes Programm zur Erklärung vorbereitet.
Die alte Schnittstelle, die ich benutze, benötigt einen Zeiger auf die Ergebnisdaten als void * und ich möchte vermeiden, dies ändern zu müssen.
Die unique_ptr im Beispiel zeigt nur, dass in meiner realen Codebasis alles, was an den Daten arbeitet, intelligente Zeiger zur Speicherverwaltung verwendet.
Mein Problem ist, dass die Ergebnisdaten kaputt gehen (siehe letzte Ausgabezeile/letzter Aufruf von printPayload); am Ende ist alles 0, aber es scheint kein Problem bei der Umwandlung in den void * und zurück zu sein, wie durch die 2. und 3. Ausgabezeile gezeigt.
Ist dies ein Problem im Zusammenhang mit Provisorien? Ich verstehe es nicht ...
Ich hoffe, diese Art von Problem hat Relevanz für einige von Ihnen.
#include <iostream>
#include <memory>
struct Payload
{
long a;
int b;
int c;
Payload() : a(), b(), c() {}
Payload(long setA, int setB, int setC) : a(setA), b(setB), c(setC) {}
};
void printPayload(const Payload& printThis)
{
std::cout << "payload -- a: " << printThis.a << " b: " << printThis.b << " c: " << printThis.c << std::endl;
}
void doSomething(Payload* sourceData, void* targetData)
{
if (!sourceData) return;
std::unique_ptr<Payload> sourceDataUnique(sourceData);
sourceDataUnique->a = 222;
sourceDataUnique->b = 333;
sourceDataUnique->c = 444;
printPayload(*sourceDataUnique);
targetData = reinterpret_cast<void*>(sourceDataUnique.release());
printPayload(*(reinterpret_cast<Payload*>(targetData)));
}
int main(void)
{
Payload* myPayload = new Payload(14, 8, 1982);
Payload myResult;
printPayload(*myPayload);
doSomething(myPayload, &myResult);
printPayload(myResult);
}
Ausgang:
payload -- a: 14 b: 8 c: 1982
payload -- a: 222 b: 333 c: 444
payload -- a: 222 b: 333 c: 444
payload -- a: 0 b: 0 c: 0
Sie setzen 'targetData' in 'doSomething', aber diese Änderung ist lokal für die Funktion. Der Parameter sollte eine Referenz sein. –
Dies kann vereinfacht werden: 'void doSomething (Payload * src, Payload * dst) {dst = src; } ' – melpomene
@ PankajDaga, das wird nicht funktionieren, da es eine Referenz auf eine temporäre sein wird. – StoryTeller