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

孤街浪徒 提交于 2019-12-04 05:04:35

问题


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:


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";


来源:https://stackoverflow.com/questions/41483552/will-creating-a-class-template-wrapper-of-a-reference-cause-undefined-behavoir

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!