2017-01-05 1 views
1

ist hier ein Code-Schnipsel:Wird das Erstellen einer Klassenvorlage-Wrapper einer Referenz Ursache undefined Behavoir verursachen?

#include <iostream> 
#include <string> 
#include <vector> 

template<class T> 
class Wrapper { 
public: 
    T& t; 
    explicit Wrapper2(T& obj) : t(obj) {} 
}; 

class Car { 
public: 
    std::string color; 
    std::string name; 
    Car(){} 
    Car(std::string colorIn, std::string nameIn) : color(colorIn), name(nameIn){} 
}; 

int _tmain(int iNumArguments, _TCHAR* pArgumentText[]) { 
    typedef Wrapper<Car> car; 

    // Create 2 Containers 
    std::vector<car> collection1; 
    std::vector<car> collection2; 

    // Populate collection 1 with reference objects 
    collection1.push_back(Car("black", "Ford")); 
    collection1.push_back(Car("white", "BMW")); 
    collection1.push_back(Car("yellow", "Audi")); 

    // use referenced object at index 0 in collection 1 
    // to populate index 0 of collection 2 
    collection2.push_back(collection1[0]); 

    // Print Out index 0 of collection2's referenced object's fields 
    std::cout << collection2[0].t.color << " " << collection2[0].t.name << std::endl; 

    // Change collection2's index 0 referenced object's fields 
    collection2[0].t.color = std::string("green"); 
    collection2[0].t.name = std::string("Gremlin"); 

    // Print out collection1's index 0 referenced object's fields 
    // and they are changed 
    std::cout << collection1[0].ptr->color << " " << collection1[0].ptr->name << std::endl; 
    return 0; 
} 

Dies kompiliert, bauen und ohne Fehler erfolgreich in MSVS2015 CE laufen.

Kann dies oder kann dies Undefined Behavior generieren und wenn ja; Wie?

+0

Sie wollen wahrscheinlich [ 'std :: reference_wrapper'] (http://en.cppreference.com/w/ cpp/utility/functional/reference_wrapper) –

+0

@VittorioRomeo Ich weiß über 'std :: reference_wrapper' Ich wollte nur wissen, ob dies zu undefiniertem Verhalten führen würde. –

+3

Sie baden in UB, weil Sie Verweise auf Provisorien speichern und später verwenden. – Quentin

Antwort

2

Wird ein Wrapper für eine Klassenvorlage einer Referenz verursacht undefiniertes Verhalten?

Nr

jedoch Verweise zu mißbrauchen (und Zeiger und Iteratoren) im Allgemeinen der Fall ist. Wenn das referenzierte Objekt zerstört wird, bleibt diese Referenz hängen. Dies geschieht mit allen Verweisen, nicht nur mit denen, die in einer Klasse eingeschlossen sind - der Wrapper hat keine Wirkung. Wenn die Referenz hängt, hat ihre Verwendung ein undefiniertes Verhalten.

collection1.push_back(Car("black", "Ford")); 

Hier Das Objekt ist ein temporär. Das Objekt existiert bis Ende push_back. Danach hängt die Referenz im Wrapper im Vektor.

std::cout << collection2[0].t.color << " " << collection2[0].t.name << std::endl; 

Hier verwenden Sie einen baumelnden Referenz und das Programm hat das Verhalten undefiniert.


Hier ist ein Beispiel die Verpackung zu verwenden, die keine UB hat:

Car c; 
collection1.push_back(c); 
collection1[0].color = "black"; 
+0

Vielen Dank für die Antwort; Dies geschah, als man eine Frage zu einem anderen Beitrag beantwortete und sie Objekte in 'std :: vector' mit mehreren Containern speichern wollte, wobei, wenn sie modifizieren,' vector2 [0] ', dann' vector1 [0] 'genauso ähnlich geändert würde wie einige Funktionen von 'python' funktionieren. Einige schlugen ihnen 'std :: reference_wrapper' und andere' shared_ptr' vor. Ich habe versucht, ihnen einen einfachen benutzerdefinierten Klassenschablonen-Wrapper zu zeigen, der entweder 'shared_ptr' oder' reference' umschließt. –

+1

@FrancisCugler Ihr Wrapper ist eine eingeschränkte Version von 'std :: reference_wrapper'. Ein Referenzwrapper funktioniert einwandfrei, wenn Sie einen "Master" -Container haben, der die Objekte selbst enthält (keine Referenzen), der * nie * modifiziert wurde, und andere Container Referenzen auf den Master haben.Mit der Alternative shared_ptr sind alle Container gleich und können frei geändert werden. – user2079303

+0

Ich habe eine Follow-up-Frage dazu hier gestellt: http://stackoverflow.com/questions/41485042/dangling-references-leading-to-undefined-behavoir –

Verwandte Themen