美文网首页C/C++程序员C++
c++临时变量的作用域

c++临时变量的作用域

作者: littlersmall | 来源:发表于2016-01-20 13:18 被阅读266次

    上上周周末翻《effective c++》,条款18看到一段代码:

    class Date {
        public:
        Date(const Month& m, const Day& d, const Year& y);
        ...
    };
    
    class Month {
        public:
        static Month Jan() { return Month(1); } 
    };
    Date d(Month::Jan(), Day(30), Year(1995));
    

    看到这里的时候,猛然感觉有问题。
    在函数d(Month::Jan(), Day(30), Year(1995));中(也就是Data的构造函数),第一个变量为const Month& m,是一个引用,而函数Jan()返回了一个临时变量(返回值保存在栈中,之后通过拷贝构造临时变量)。也就是说,将一个引用指向了一个临时变量,而且这个临时变量的作用域非常不明确。初看上去,在Data()的第一个参数赋值完成后,临时变量就失效了。

    当时在网上找了好久,期望看到其他人对这段代码的异议,可惜没有发现。
    周二的时候,问了一下师兄。
    师兄说这样是有问题的,估计编译都会出现警告,但是如果Date的构造函数中做了特殊的实现(比如变量拷贝等等),那么这样写就是正确的。我想了想,确实有道理,师兄还提出了一个观点:c++里似乎会延长这样的临时变量的作用域。他建议我去看一下这段代码的汇编实现,就能彻底搞清楚了。
    可是我不以为然,想当然的笃定这样的代码肯定会编译失败。
    而且觉得,这样的可能存在争议的代码,本来就不应该写出来,如果是我来实现,会在static Month Jan()中增加一个static Month(1)成员,效率高,逻辑清晰。

    以至于后来也确实没有去反汇编这段代码,甚至都没有去验证是否存在编译警告问题......
    这件事本来就这样过去了,可是今天继续翻《effective c++》的时候,又看到了一段代码:

    class Rational {
        public:
        Rational(int numberator = 0,
                    int denominator = 1); //允许隐式转换
        ...
    };
    const Rational operator* (const Rational& lhs,
                                const Rational& rhs)
    {...}
    Rational oneFourth(1, 4);
    Rational result;
    result = 2 * oneFourth;
    

    明显的,这里一样使用了临时变量,书上明确写了一句话: “万岁,通过编译了”。
    看来这样做,编译是可以成功的,而且好像是一种再普通不过的用法。
    于是一边哀叹自己的浅薄,一边去查资料搞定这个问题。
    终于在c++标准里找到这样的解释:

    C++标准对临时对象的生存期(life time)的规定,可见标准12.2节第3-5条。第3条讨论了临时对象的析构时间:
    3 .... Temporary objects are destroyed as the last step in evaluating the full-expression (1.9) that (lexically) contains the point where they were created. This is true even if that evaluation ends in throwing an exception.(这其中涉及到的full-expression的定义,参见1.9节,一般指对一个变量的初始化)。
    但在第4、5条中,分别讨论了两个例外情形,
    1 将临时对象作为初始化因子,例如string s = string("hello world");
    2 将一个常量引用变量绑定到这个临时对象上。
    在这两种情况中可以通过一个名字来存取这个对象,此对象的生存期就将延长到变量名的作用域结束。除此之外,都按照第3条处理。

    这样解释之后,一切顺理成章。
    (原文时间2013-10-1)

    相关文章

      网友评论

        本文标题:c++临时变量的作用域

        本文链接:https://www.haomeiwen.com/subject/hiklkttx.html