C++表达式中临时对象的销毁

发布于 2024-08-13 03:23:40 字数 675 浏览 8 评论 0原文

给出以下代码:

#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++ 知识的人可以向我解释一下吗?

Given the following code:

#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;
}

I get the following output:

ctor
42
dtor

While I know this is correct, I'm not certain why. Is there anyone with stdc++ knowledge who can explain it to me?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

书间行客 2024-08-20 03:23:40

临时对象在评估完整表达式 (1.9) 的最后一步被销毁,该完整表达式 (1.9)(从词法上)包含它们的创建点。 [12.2/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. [12.2/3]

黑凤梨 2024-08-20 03:23:40

12.2 临时对象,第 3 条:“临时对象在计算(词法上)包含它们创建点的完整表达式 (1.9) 的最后一步时被销毁。”

1.9 程序执行,第 12 条:“完整表达式是不是另一个表达式的子表达式的表达式。”

12.2 Temporary objects, clause 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."

1.9 Program execution, clause 12: "A full-expression is an expression that is not a subexpression of another expression."

简单气质女生网名 2024-08-20 03:23:40

由于有一个构造函数可以接受传递给 F() 函数的参数,因此编译器在将参数放入堆栈之前动态创建对象。正如下面的反汇编中所示。默认情况下,文字数字被视为整数,因此存在可接受的转换。

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

Since there is a constructor which can accept the argument passed into the F() function the complier creates the object on the fly before putting the arguments on the stack. As can be see in the disassembly below. literal numbers are treated by default as ints so there is an acceptable conversion.

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) 

Your temp object hangs around until the expression is fully evaluated. this can be made more evident if you add another call to your function.

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

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

    return 0;
}

Which has an output of

ctor
42
dtor
ctor
80
dtor
本宫微胖 2024-08-20 03:23:40

f(42) 隐式构造一个未命名的 implicit_t。它在其包含范围内有效,就像任何 auto 变量一样。自然地,d'tor 在 main()return 0; 上被调用。

f(42) constructs an unnamed implicit_t implicitly. It lives for the duration of it's containing scope, just as any auto variable would. Naturally, the d'tor gets called on return 0; of main().

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文