0

Ich habe zwei Funktionen.C++: Übergeben Sie ein std :: vector <> Element durch Verweis auf ein temporäres Objekt

function1 ruft function2 auf, die einen Verweis auf ein Objekt zurückgibt, das ich dann zum Aufrufen einer öffentlichen Funktion verwendet.

function1(function2).returned_object.mymethod(); 

Dies ist eine ziemlich unhandliche Art, Dinge zu tun, aber es funktioniert.

Jetzt habe ich ein Problem, wo ich eine Methode aufrufen muss, dann eine andere Methode, also brauche ich ein temporäres Objekt.

Meine Frage ist, wie kann ich ein temporäres Objekt deklarieren, das das Objekt speichert, das als Referenz zurückgibt. Ich schätze, ich brauche einen Zeiger.

Das andere Problem ist, temp_obj ist in einem Vektor enthalten, und ich bin besorgt über Konflikte dort und Speicherverlust. Wenn ich einen Zeiger verwende, muss ich dann auch einen Destruktor verwenden?

Hier ist der relevante Code:

bool Machine::perform_function(std::vector<Job>& jobs) { 
    bool add = true; 

    if (can_fail) { 
     add = coin_toss(); 

    } 

    for (int i = 0; i < my_jobs.size(); i++) { 

     if (add) { 
      find_job(my_jobs[i], jobs).toggle(name, item_name, true); 

     } 
     if (!add) { 
      find_job(my_jobs[i], jobs).toggle(name, item_name, false); 

     } 
    } 

    return add; 
} 


Job& Machine::find_job(std::string jobname, std::vector<Job>& jobs) { 

    for (int i = 0; i < jobs.size(); i++) { 

     if (jobs[i].is_job(jobname)) { 
      return jobs[i]; 

     } 
    } 
} 
+0

"Wie kann ich ein temporäres Objekt deklarieren, das die Funktion speichert, die als Referenz zurückgibt" - Sie können keine Funktion in einem Objekt speichern. – immibis

Antwort

1

Es ist völlig in Ordnung, das Ergebnis als Referenz zu speichern:

ClassName & temp_obj = function1(function2); 
temp_obj.method1(); 
temp_obj.method2(); 

Ihre andere Frage hier:

Das andere Problem ist , temp_obj ist in einem Vektor enthalten, und ich bin besorgt über Konflikte dort und Speicherverlust.

Es ist in Ordnung, jobs[i] als Referenz zurückzugeben. Die operator[] auf einem Vektor gibt eine Referenz selbst zurück. Vorausgesetzt, dass Sie den Vektor nicht so ändern, dass er den Verweis auf das Objekt ändert und Sie keinen Verweis auf ein Objekt speichern, das zerstört wurde, können Sie es verwenden.

Wenn Ihre temporäre Referenz den Gültigkeitsbereich verlässt, passiert nichts. Es ist nur eine Referenz.

+0

Was passiert, wenn die Referenz den Gültigkeitsbereich verlässt? – bigcodeszzer

+0

@bigcodeszzer: nichts, eine Referenz besitzt kein Objekt, noch kann es ein Leck verursachen, es ist nur ein Alias ​​für ein existierendes Objekt. – Jack

+0

fair genug .... – bigcodeszzer

2

Sie benötigen eine temporäre Variable, aber diese temporäre Variable könnte eine Referenz sein, so dass keine Kopie erstellt wird und Sie sicher sind, sie zu verwenden.

aber noch besser, könnte man <algorithm> Funktionen nutzen zu tun, was Sie brauchen, ohne das Rad neu erfinden zu müssen:

std::string name = ...; 
auto it = std::find_if(begin(jobs), end(jobs), [&name] (const Job& job) { return job.is_job(name); }); 

if (it != jobs.end()) 
{ 
    it->method1(); 
    it->method2(); 
} 
1

Unter der Annahme, es function1() ist, die einen Verweis zurückgibt (Ihre Frage, dass unklar ist), verwenden Sie einfach eine Referenz

ClassName &temp_obj = function1(function2); 

temp_obj.method1(); 
temp_obj.method2(); 

Wenn function1() eine const Referenz zurückgibt, als temp muss auch sein const.

Die Einschränkung dabei ist, dass eine Referenz nach der Erstellung nicht erneut eingefügt werden kann (um auf ein anderes Objekt zu verweisen). Zum Beispiel in;

ClassName &temp_obj = function1(function2); // initialisation 

temp_obj = function1(some_other_function);  // reassignment 
temp_obj.method1(); 
temp_obj.method2(); 

die Neuzuordnung wird temp nicht neu einsetzen, auch wenn function1() auf dem zweiten Aufruf eine andere Referenz zurückgibt. Stattdessen wird das Objekt, auf das verwiesen wird, zugewiesen (vorausgesetzt, es hat einen funktionierenden Zuweisungsoperator). Wenn Sie eine Variable möchten, die sich im Laufe der Zeit auf andere Objekte beziehen kann, benötigen Sie einen Zeiger.

ClassName *temp_obj = &function1(function2); // assumes function1() returns a reference 

temp_obj = &function1(some_other_function);  // reassigns the pointer 

temp_obj->method1(); 
temp_obj->method2();