Here is a code snippet:
#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;
}
This does compile, build and run successfully in MSVS2015 CE without any errors.
Does this or can this generate Undefined Behavior and if so; How?
No.
However misusing references (and pointers and iterators) in general does. If the referenced object is destroyed, that reference is left dangling. This happens to all references, not only those wrapped in a class - the wrapper has no effect. When the reference dangles, using it has undefined behaviour.
Here, The object is a temporary. The object exists until the end of
push_back
. After that the reference in the wrapper in the vector is dangling.Here you use a dangling reference and the program has undefined behaviour.
Here is an example of using the wrapper that has no UB: