• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-59  評論-36  文章-0  trackbacks-0
            看了如下的文字,對臨時對象有了一些初步了解。

            摘自 ISO C++ 2003      P191

            12.2 Temporary Object

             

            1 Temporaries of class type are created in various contexts: binding an rvalue to a reference (8.5.3), returning an rvalue (6.6.3), a conversion that creates an rvalue (4.1, 5.2.9, 5.2.11, 5.4), throwing an exception (15.1), entering a handler (15.3), and in some initializations (8.5). [Note: the lifetime of exception objects is described in 15.1.] Even when the creation of the temporary object is avoided (12.8), all the semantic restrictions must be respected as if the temporary object was created. [ Example: even if the copy constructor is not called, all the semantic restrictions, such as accessibility (clause 11), shall be satisfied.]

            總結(jié):
            臨時對象產(chǎn)生于引用綁定右值、函數(shù)返回右值、轉(zhuǎn)換、拋出異常以及一些初始化試。
            注,即使有些臨時對象可以被優(yōu)化掉,但語義的要求必須滿足

            例如:

            class X 
            {
            public:
                X (
            const X &a); // No copy constructor definition
            }
            ;

            X f()
            {
                X one;
                
            return one;
            }

            int main()
            {
                X one 
            = f();  // VC2005中,release編譯時盡管優(yōu)化掉了復(fù)制構(gòu)造,但仍需要復(fù)制構(gòu)造的存在以滿足語義要求
            }

            2 [Example:

            class X {
            // ...
            public:
            // ...

            X(int);
            X(const X&);
            ˜X();
            };

            X f(X);
            void g()
            {
            X a(1);
            X b = f(X(2));
            a = f(a);
            }

            Here, an implementation might use a temporary in which to construct X(2) before passing it to f() using X’s copy-constructor; alternatively, X(2) might be constructed in the space used to hold the argument. Also, a temporary might be used to hold the result of f(X(2)) before copying it to b using X’s copyconstructor; alternatively, f()’s result might be constructed in b. On the other hand, the expression a=f(a) requires a temporary for either the argument a or the result of f(a) to avoid undesired aliasing of a. ]

            總結(jié):
            對于f(X(2))這樣形式的參數(shù)傳入和值的返回,并不一定必須產(chǎn)生臨時對象,然后由復(fù)制構(gòu)造來構(gòu)造,也可以直接在目標(biāo)內(nèi)存中構(gòu)造(形參或接受返回值的對象的所在地址)。這就是說,可以不經(jīng)復(fù)制構(gòu)造而直接構(gòu)造對象,但如之前所說復(fù)制構(gòu)造必須存在。

            3 When an implementation introduces a temporary object of a class that has a non-trivial constructor (12.1), it shall ensure that a constructor is called for the temporary object. Similarly, the destructor shall be called for a temporary with a non-trivial destructor (12.4). 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.

            總結(jié):
            當(dāng)產(chǎn)生臨時對象的完整表達(dá)式計算完時,臨時對象就會被析構(gòu)

             

            4 There are two contexts in which temporaries are destroyed at a different point than the end of the full-expression. The first context is when an expression appears as an initializer for a declarator defining an object.In that context,the temporary that holds the result of the expression shall persist until the object’s initialization is complete. The object is initialized from a copy of the temporary; during this copying, an implementation can call the copy constructor many times; the temporary is destroyed after it has been copied, before or when the initialization completes. If many temporaries are created by the evaluation of the initializer, the temporaries are destroyed in reverse order of the completion of their construction.

            總結(jié):
            有兩個情況下,不在完整表達(dá)式完成時析構(gòu)。第一種情況是,當(dāng)一個表達(dá)式出現(xiàn)在初始化式中時,當(dāng)執(zhí)行完初始化之后才會析構(gòu)

            例如: 

            int main()
            {
                X a,b;
                X c;
                cout 
            << "----------"<<endl;
                c
            =a+b; // 臨時對象在對c進(jìn)行完賦值后析構(gòu),即臨時對象在下面語句執(zhí)行前析構(gòu)
                cout << "----------"<<endl;
            }



            5 The second context is when a reference is bound to a temporary. The temporary to which the reference is bound or the temporary that is the complete object to a subobject of which the temporary is bound persists for the lifetime of the reference except as specified below. A temporary bound to a reference member in a constructor’s ctor-initializer (12.6.2) persists until the constructor exits.A temporary bound to a reference parameter in a function call (5.2.2) persists until the completion of the full expression containing the call.A temporary bound to the returned value in a function return statement (6.6.3) persists until the function exits.In all these cases, the temporaries created during the evaluation of the expression initializing the reference, except the temporary to which the reference is bound,are destroyed at the end of the full-expression in which they are created and in the reverse order of the completion of their construction.If the lifetime of two or more temporaries to which references are bound ends at the same point, these temporaries are destroyed at that point in the reverse order of the completion of their construction. In addition, the destruction of temporaries bound to references shall take into account the ordering of destruction of objects with static or automatic storage duration (3.7.1, 3.7.2); that is, if obj1 is an object with static or automatic storage duration created before the temporary is created, the temporary shall be destroyed before obj1 is destroyed; if obj2 is an object with static or automatic storage duration created after the temporary is created, the temporary shall be destroyed after obj2 is destroyed.[Example:

            class C {

            // ...

            public:
            C();
            C(int);
            friend C operator+(const C&, const C&);
            ˜C();
            };
            C obj1;
            const C& cr = C(16)+C(23);
            C obj2;

            the expression C(16) + C(23) creates three temporaries. A first temporary T1 to hold the result of the expression C(16), a second temporary T2 to hold the result of the expression C(23), and a third temporary T3 to hold the result of the addition of these two expressions. The temporary T3 is then bound to the reference cr.It is unspecified whether T1 or T2 is created first. On an implementation where T1 is created before T2, it is guaranteed that T2 is destroyed before T1. The temporaries T1 and T2 are bound to the reference parameters of operator+; these temporaries are destroyed at the end of the full expression containing the call to operator+. The temporary T3 bound to the reference cr is destroyed at the end of cr’s lifetime, that is, at the end of the program. In addition, the order in which T3 is destroyed takes into account the destruction order of other objects with static storage duration. That is, because obj1 is constructed before T3, and T3 is constructed before obj2, it is guaranteed that obj2 is destroyed before T3, and that T3 is destroyed before obj1. ]

            總結(jié):
            第二種情況是,當(dāng)一個引用綁定臨時對象時,只有當(dāng)引用或臨時對象超出作用域時析構(gòu)(因為當(dāng)臨時對象被析構(gòu)后,指向該臨時對象的引用也就自然沒用了)

            例如

            int main()
            {
                X a,b;
                cout 
            << "----------"<<endl;
                X 
            &c=a+b;  // 臨時對象因被引用,故而延期析構(gòu)
                cout << "----------"<<endl;
                 
            return 0// 此時臨時對象析構(gòu)
            }


            另,發(fā)現(xiàn)對于指針,則完全沒有什么因臨時對象被“引用”而延長生命期這一說法

            class T
            {
            int i;
            public:
            T()
            { i = 99; }
            void show(){ cout << i<<endl; }
            }
            ;
            int main()
            {
                T 
            *p;
                cout 
            << "========="<<endl;
                p
            =&f();  // f函數(shù)一旦調(diào)用完,臨時對象就被析構(gòu)
            (*p).show(); // 輸出垃圾值
                cout << "========="<<endl;
                cout 
            << "return"<<endl;
            }

            posted on 2009-05-24 15:53 zhaoyg 閱讀(804) 評論(1)  編輯 收藏 引用 所屬分類: C/C++學(xué)習(xí)筆記

            評論:
            # re: {偶爾學(xué)習(xí)C++標(biāo)準(zhǔn)} 之 [初識臨時對象生命期] 2010-08-09 20:57 | 希望2012是真的,真心期待!!!
            很不錯!!!!!!!  回復(fù)  更多評論
              
            国产精品久久久久乳精品爆| 午夜精品久久久久久| 久久人人添人人爽添人人片牛牛| 国产成人精品久久| 97久久精品人人做人人爽| 国产亚洲欧美精品久久久| 久久久久久综合网天天| 久久久久av无码免费网| 久久久免费观成人影院| 亚洲国产成人久久笫一页| 色8激情欧美成人久久综合电| 欧美色综合久久久久久| 亚洲欧美精品一区久久中文字幕| 日本精品久久久久久久久免费| 久久久久这里只有精品| 久久精品国产久精国产果冻传媒 | 日韩乱码人妻无码中文字幕久久| 亚洲精品国产第一综合99久久| 久久无码精品一区二区三区| 久久综合一区二区无码| 久久AV高潮AV无码AV| 久久精品亚洲精品国产色婷| 国内精品伊人久久久久| 久久国产成人午夜aⅴ影院| 日韩人妻无码一区二区三区久久99 | 久久亚洲国产精品成人AV秋霞| 伊人久久精品无码av一区| 欧美牲交A欧牲交aⅴ久久| 99久久精品免费看国产一区二区三区| 久久久久无码精品| 亚洲中文字幕无码一久久区| 久久精品国产精品青草app| 欧美伊人久久大香线蕉综合69| 亚洲AV日韩精品久久久久久久| 久久被窝电影亚洲爽爽爽| 伊人久久大香线蕉精品不卡| 久久精品国产亚洲AV无码偷窥| 久久精品国产亚洲Aⅴ蜜臀色欲| 香蕉久久夜色精品升级完成| 99久久精品免费| 97久久精品无码一区二区|