Will creating a class template wrapper of a refere

2019-03-02 12:27发布

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?

1条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-03-02 12:53

Will creating a class template wrapper of a reference cause undefined behavoir?

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.

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

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.

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

Here you use a dangling reference and the program has undefined behaviour.


Here is an example of using the wrapper that has no UB:

Car c;
collection1.push_back(c);
collection1[0].color = "black";
查看更多
登录 后发表回答