创建引用的类模板包装器会导致未定义的行为吗? [英] Will creating a class template wrapper of a reference cause undefined behavoir?

查看:37
本文介绍了创建引用的类模板包装器会导致未定义的行为吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个代码片段:

#include #include <字符串>#include <向量>模板类包装{民众:夯;t;显式 Wrapper2( T& obj ) : t(obj) {}};类汽车{民众:std::string 颜色;std::string 名称;车(){}汽车( std::string colorIn, std::string nameIn ) : color( colorIn ), name( nameIn ){}};int _tmain( int iNumArguments, _TCHAR* pArgumentText[] ) {typedef Wrapper车;//创建 2 个容器std::vector收藏1;std::vector收藏2;//用引用对象填充集合 1collection1.push_back( Car("black", "Ford") );collection1.push_back( Car("white", "BMW") );collection1.push_back( Car("yellow", "Audi") );//使用集合 1 中索引 0 处的引用对象//填充集合 2 的索引 0collection2.push_back( collection1[0]);//打印出 collection2 引用对象字段的索引 0std::cout <<collection2[0].t.color<<" " <<collection2[0].t.name<颜色<<" " <<集合1[0].ptr->名称<

这确实在 MSVS2015 CE 中成功编译、构建和运行,没有任何错误.

这样做或是否会产生未定义的行为,如果是这样;怎么样?

解决方案

创建引用的类模板包装器会导致未定义的行为吗?

没有

然而,滥用引用(以及指针和迭代器)通常确实如此.如果引用的对象被销毁,则该引用将悬空.所有引用都会发生这种情况,而不仅仅是那些包装在类中的引用 - 包装器不起作用.当引用悬空时,使用它具有未定义的行为.

<块引用>

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

这里,对象是临时的.该对象一直存在到 push_back 结束.之后,向量中包装器中的引用悬空.

<块引用>

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

这里您使用了悬空引用,并且程序具有未定义的行为.

<小时>

以下是使用没有 UB 的包装器的示例:

Car c;collection1.push_back(c);collection1[0].color = "黑色";

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?

解决方案

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

这篇关于创建引用的类模板包装器会导致未定义的行为吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆