2

次のコードが与えられます:

#include <iostream>

struct implicit_t
{
    implicit_t(int x) :
        x_m(x)
    {
        std::cout << "ctor" << std::endl;
    }

    ~implicit_t()
    {
        std::cout << "dtor" << std::endl;
    }

    int x_m;
};

std::ostream& operator<<(std::ostream& s, const implicit_t& x)
{
    return s << x.x_m;
}

const implicit_t& f(const implicit_t& x)
{
    return x;
}

int main()
{
    std::cout << f(42) << std::endl;

    return 0;
}

次の出力が得られます。

ctor
42
dtor

これが正しいことはわかっていますが、理由はわかりません。stdc ++の知識を持っていて、私に説明してくれる人はいますか?

4

4 に答える 4

13

一時オブジェクトは、それらが作成されたポイントを(字句的に)含む完全式(1.9)を評価する最後のステップとして破棄されます。[12.2 / 3]

于 2009-12-03T01:41:08.563 に答える
6

12.2一時オブジェクト、第3項:「一時オブジェクトは、(字句的に)作成されたポイントを含む完全式(1.9)を評価する最後のステップとして破棄されます。」

1.9プログラムの実行、第12節:「完全な式は、別の式の部分式ではない式です。」

于 2009-12-03T01:42:58.707 に答える
1

F()関数に渡された引数を受け入れることができるコンストラクターがあるため、コンパイラーは、引数をスタックに配置する前に、その場でオブジェクトを作成します。以下の分解で見ることができるように。リテラル数はデフォルトでintとして扱われるため、許容可能な変換があります。

001115C5  call        implicit_t::implicit_t (11112Ch) 
001115CA  mov         dword ptr [ebp-4],0 
001115D1  mov         esi,esp 
001115D3  mov         eax,dword ptr [__imp_std::endl (11A308h)] 
001115D8  push        eax  
001115D9  lea         ecx,[ebp-0D4h] 
001115DF  push        ecx  
001115E0  call        f (111113h) 

式が完全に評価されるまで、一時オブジェクトはハングします。これは、関数に別の呼び出しを追加すると、より明確になります。

int main()
{
    std::cout << f(42) << std::endl;

    std::cout <<f(80) << std::endl;

    return 0;
}

の出力があります

ctor
42
dtor
ctor
80
dtor
于 2009-12-03T01:43:00.017 に答える
-4

f(42)名前のないものをimplicit_t暗黙的に作成します。auto他の変数と同じように、スコープが含まれている間は存続します。当然、d'torはのに呼び出されreturn 0;ますmain()

于 2009-12-03T01:40:26.310 に答える