代码之家  ›  专栏  ›  技术社区  ›  Michael Mrozek

作为函数调用的一部分创建的临时表何时被销毁?

  •  19
  • Michael Mrozek  · 技术社区  · 15 年前

    几乎不可能是一致的,所以举个例子:

    class A {
    public:
        A(int x) : x(x) {printf("Constructed A(%d)\n", x);}
        ~A() {printf("Destroyed A\n");}
    
        int x;
        int* y() {return &x;}
    };
    
    void foo(int* bar) {
        printf("foo(): %d\n", *bar);
    }
    
    int main(int argc, char** argv) {
        foo(A(4).y());
    }
    

    如果 A(4) foo 它绝对不会被摧毁,直到 A 会被摧毁 甚至开始了,但是用GCC4.3.4测试表明不是这样;输出为:


    foo():4

    问题是, GCC的行为是否得到规范的保证 ,使指向我正在使用的成员的指针无效?

    4 回复  |  直到 15 年前
        1
  •  20
  •   James McNellis    15 年前

    临时对象一直存在,直到创建它们的完整表达式结束。

    在你的例子中 A 对象创建者 A(4) 直到表达式在调用返回之后结束 foo() .

    语言标准保证了这种行为:

    可以通过将引用绑定到临时对象来延长临时对象的生存期(在这种情况下,它的生存期将延长到引用的生存期结束),或者通过将它用作构造函数的初始值设定项列表中的初始值设定项(在这种情况下,它的生存期将延长到正在构造的对象完全构造)。

        2
  •  6
  •   Jerry Coffin    15 年前

    §12.2/3:“临时对象被销毁,作为评估完整表达式(1.9)的最后一步,该表达式(词汇上)包含创建它们的点。”

    A 物体必须在 foo 返回。

        3
  •  2
  •   anon anon    15 年前

        4
  •  -2
  •   Greg Domjan    15 年前

    临时对象的生存期 A(4) 会持续很长时间 y()

    记忆指向了 y() 不可靠,这取决于线程和分配,它可能会被重新分配,并且在调用 foo() 利用它。

    推荐文章