【问题标题】:Reference member binds to a temporary object whose life-time would be shorter than the lifetime of the constructed object引用成员绑定到一个临时对象,其生命周期将短于构造对象的生命周期
【发布时间】:2020-10-25 14:28:25
【问题描述】:

我在尝试初始化 Context 时遇到以下编译器错误:

引用成员 'context' 绑定到一个临时对象,其生命周期将短于构造对象的生命周期

。编译器指的是什么临时的objectonEventInternalstatic 所以生命周期不能再短了

class Event {};

class Context {
    Context(int width, int height, void(*eventCallback)(Event&)) {}
};

class App {

    App(int w, int h): context{w, h, onEventInternal } {} // Error here! 

    static void onEventInternal(Event& event) {
        //event handling
    }
    
private:
    const Context& context;
};

【问题讨论】:

    标签: c++


    【解决方案1】:

    在构造函数的初始化部分:

    context{w, h, onEventInternal }
    

    这会构造一个临时的Context 对象,将对该对象的引用存储在context 类成员中。到现在为止还挺好。然后,一旦构造函数返回这个临时对象就被销毁,留下context 作为对被销毁对象的引用。对该类成员的任何后续使用都将导致未定义的行为。

    context 是一个参考。它不是一个对象。这就是引用的含义:它是对某个其他对象的引用。

    引用所指的对象是完全不同的独立对象。

    你必须构造这个引用来引用其他一些现有的对象。

    您的构造函数会这样做,但它是一个临时对象,并且您的编译器足够聪明,可以弄清楚并警告您处于demons flying out of your nose 的高风险中。

    您需要将类成员更改为独立对象,而不是引用,或者将引用传递给构造函数,并让构造函数将类成员设置为对其他对象的传入引用。

    【讨论】:

      【解决方案2】:

      编译器指的是什么临时对象?

      您正在成员初始化器列表中构造一个临时的Context 并将其绑定到引用成员context。临时的将立即被销毁并留下context 悬空。

      App(int w, int h): context{w, h, onEventInternal } {}
      //                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      // constructing a temporary Context and bind to context
      

      class.base.init#8

      绑定到一个引用成员的临时表达式 mem-initializer 格式不正确。 [示例 5:

      struct A {
        A() : v(42) { }   // error
        const int& v;
      };
      

      ——结束示例]

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-07
        • 1970-01-01
        • 2011-04-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多