C++ 悬空引用导致未定义的行为

C++ 悬空引用导致未定义的行为,c++,reference,undefined-behavior,C++,Reference,Undefined Behavior,我之前问过一个关于引用和未定义行为的问题:根据给出的答案和一些评论,比如用户2079303的评论,他们在其中指出: 如果您有一个“主”容器,其中包含从未修改过的对象本身(而不是引用),并且其他容器具有对主容器的引用,那么引用包装器可以正常工作 我的新问题是:这是否有助于减少悬空引用导致未定义行为的可能性 template<class T> class Wrapper { private: T object; public: T& referenced_obje

我之前问过一个关于引用和未定义行为的问题:根据给出的答案和一些评论,比如用户2079303的评论,他们在其中指出:

如果您有一个“主”容器,其中包含从未修改过的对象本身(而不是引用),并且其他容器具有对主容器的引用,那么引用包装器可以正常工作

我的新问题是:这是否有助于减少悬空引用导致未定义行为的可能性

template<class T>
class Wrapper {
private:
    T object;
public:
    T& referenced_object;
    explicit Wrapper( T& obj ) : object(obj), referenced_object( object ) {}
};
模板
类包装器{
私人:
T对象;
公众:
T&u对象;
显式包装器(T&obj):对象(obj),引用对象(object){
};

它将以与前一个问题相同的方式使用,其中多个容器将包含相同的引用对象,如果一个容器中修改了一个对象,则该对象的相应引用也将在另一个容器中修改。

这样的包装没有意义,如果存储副本本身,则无需引用。当您移动此对象时,您的引用将无效(例如,当它存储在
std::vector
中并重新分配内存时)


引用和
std::reference\u wrapper
工作正常,但不要移动对象。将对象保存在
std::list
中可以保证它们不会被移动,因此您可以使用它并将多个容器中的引用指向它的对象。

这样的包装器没有意义,如果您存储副本本身,则无需引用。当您移动此对象时,您的引用将无效(例如,当它存储在
std::vector
中并重新分配内存时)

引用和
std::reference\u wrapper
工作正常,但不要移动对象。将对象保留在
std::list
中可以保证它们不会被移动,因此您可以使用它并将多个容器中的引用指向其对象

这是否有助于减少悬空引用导致未定义行为的可能性

template<class T>
class Wrapper {
private:
    T object;
public:
    T& referenced_object;
    explicit Wrapper( T& obj ) : object(obj), referenced_object( object ) {}
};
它会。。。但是这个包装器的每个实例都将保存它们自己的对象,因此它无法实现“多个容器将保存相同的引用对象”的原始目标

此外,隐式复制/移动构造函数/赋值将复制/移动内部对象,但引用的副本将引用原始对象而不是副本-这再次导致挂起引用的可能性

此包装的引用似乎没有任何作用

这是否有助于减少悬空引用导致未定义行为的可能性

template<class T>
class Wrapper {
private:
    T object;
public:
    T& referenced_object;
    explicit Wrapper( T& obj ) : object(obj), referenced_object( object ) {}
};
它会。。。但是这个包装器的每个实例都将保存它们自己的对象,因此它无法实现“多个容器将保存相同的引用对象”的原始目标

此外,隐式复制/移动构造函数/赋值将复制/移动内部对象,但引用的副本将引用原始对象而不是副本-这再次导致挂起引用的可能性


此包装的引用似乎没有任何用途。

包含一个副本不是违背了包装的用途吗?如果查看
std::reference\u wrapper
它不允许从临时对象创建,因此意味着必须从已经存在的对象创建它。只要你了解被引用对象的生命周期,这是一件有效的事情。@PaulRooney嗯,我在上一个问题中给出了包装器,作为对另一个问题的回答,其他人说这是一个糟糕的设计,它将导致悬挂引用,从而导致未定义的行为。然后我问了前面的问题,用户2079303的回答让我想到了这一点。我的想法是将一个有效的对象作为私有对象,但只能有一个可访问的引用,然后你的评论再次说明它违背了目的。我确实知道std::reference_wrapper,但我试图做一个非常简单的包装。这取决于您如何设计代码。如果引用某个对象或指向某个对象的非拥有指针的对象比该对象更长寿,那么您就有问题了。但是,如果要将它们传递给函数,这是可以的,因为函数运行时变量必须处于活动状态(不考虑线程)。你真的需要坐下来看看设计,并确保你没有被引用的对象不超过引用的情况;我当时的想法与这些评论类似,但当其他人写下我之前的答案时,我开始怀疑自己。包括一份副本不是违背了包装的目的吗?如果查看
std::reference\u wrapper
它不允许从临时对象创建,因此意味着必须从已经存在的对象创建它。只要你了解被引用对象的生命周期,这是一件有效的事情。@PaulRooney嗯,我在上一个问题中给出了包装器,作为对另一个问题的回答,其他人说这是一个糟糕的设计,它将导致悬挂引用,从而导致未定义的行为。然后我问了前面的问题,用户2079303的回答让我想到了这一点。我的想法是将一个有效的对象作为私有对象,但只能有一个可访问的引用,然后你的评论再次说明它违背了目的。我确实知道std::reference_wrapper,但我试图做一个非常简单的包装。这取决于您如何设计代码。如果引用某个对象或指向某个对象的非拥有指针的对象比该对象更长寿,那么您就有问题了。但是,如果要将它们传递给函数,这是可以的,因为变量必须是