哪个是正确的?〜关于临时对象〜 [英] which on is correct?~about temp object~

查看:51
本文介绍了哪个是正确的?〜关于临时对象〜的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

全部,

我正在阅读[C ++模板]的ch.20-智能指针。

我正在努力。 hpp测试。但是有一些不同的东西比我想象的还要多,我发现那是关于临时对象的。所以我将这个问题简化为以下代码:


===代码开始===

#include< iostream>

使用命名空间std;


class H

{

public:

H(int i){cout<< " H" << ENDL; }

};


class T

{

public:

T(int i){cout<< " T" << ENDL; }

T(H& h){cout<< " HT" << ENDL; }

T(T const& rhs){cout<< " TT" << ENDL; }

};


T foo()

{

int i = 10;

返回i;

}


T吧()

{

H h(11);

返回h;

}


int main()

{

T t1(foo());

T t2(bar());

返回0;

}

===代码结束===


在我的win2k盒子上,我都使用bcb和devc ++来测试它:

=== bcb输出===

t

tt

h

ht

tt

=== devc ++输出===

t

h

ht

=============


好​​吧,虽然bcb是对的,因为foo()和bar()生成

temp obj,应该用来复制构造返回T.


无论如何,我想知道哪个是正确的,我的意思是,std兼容。

如果它不是bcb,为什么?


谢谢。

all,
i''m reading ch.20 -smart pointers- of [C++ Template].
and i''m tring the trule.hpp test. but there''s something different
than i expect, and i found that''s about temp object. so i simplified
the question into the following code:

===code starts===
#include <iostream>
using namespace std;

class H
{
public:
H(int i){ cout << "h" << endl; }
};

class T
{
public:
T(int i){ cout << "t" << endl; }
T(H& h){ cout << "ht" << endl; }
T(T const & rhs){ cout << "tt" << endl; }
};

T foo()
{
int i = 10;
return i;
}

T bar()
{
H h(11);
return h;
}

int main()
{
T t1(foo());
T t2(bar());
return 0;
}
===code ends===

on my win2k box, i both use bcb and devc++ to test it:
===bcb output===
t
tt
h
ht
tt
===devc++ output===
t
h
ht
=============

well, i though bcb was right, cause both foo() and bar() generate
temp obj, and which should be use to copy contruct the return T.

anyway, i want to know which is correct, i mean, std compliant.
if it''s not bcb, why?

thanks.

推荐答案

cf **** @ gmail.com 写道:
我正在阅读ch.20 -smart指针 - 的[ C ++模板]。
我正在尝试trule.hpp测试。但是有一些不同于我想象的东西,我发现那是关于临时对象的。所以我将问题简化为以下代码:

===代码开始===
#include< iostream>
使用命名空间std;

上课H
{
公开:
H(int i){cout<< " H" << ENDL; *
};

类T
公开:
T(int i){cout<< " T" << ENDL; T(H& h){cout<< " HT" << ENDL; T(T const& rhs){cout<< " TT" << ENDL; }
};

T foo()
{
int i = 10;
返回i;
}

T吧()
{
H h(11);
返回h;
}



{t / T t1(foo());
T t2(bar());
返回0;
}
===代码结束=== <在我的win2k盒子上,我都用bcb和devc ++来测试它:
=== bcb输出===
t
tt
h
ht
tt
=== devc ++输出===
t
ht
========== ===

好吧,我虽然bcb是对的,因为foo()和bar()生成了
temp obj,应该用它来复制构造返回T.无论如何,我想知道哪个是正确的,我的意思是,std是否合规。
如果它不是bcb,为什么?
i''m reading ch.20 -smart pointers- of [C++ Template].
and i''m tring the trule.hpp test. but there''s something different
than i expect, and i found that''s about temp object. so i simplified
the question into the following code:

===code starts===
#include <iostream>
using namespace std;

class H
{
public:
H(int i){ cout << "h" << endl; }
};

class T
{
public:
T(int i){ cout << "t" << endl; }
T(H& h){ cout << "ht" << endl; }
T(T const & rhs){ cout << "tt" << endl; }
};

T foo()
{
int i = 10;
return i;
}

T bar()
{
H h(11);
return h;
}

int main()
{
T t1(foo());
T t2(bar());
return 0;
}
===code ends===

on my win2k box, i both use bcb and devc++ to test it:
===bcb output===
t
tt
h
ht
tt
===devc++ output===
t
h
ht
=============

well, i though bcb was right, cause both foo() and bar() generate
temp obj, and which should be use to copy contruct the return T.

anyway, i want to know which is correct, i mean, std compliant.
if it''s not bcb, why?




我认为两者都可以。在初始化期间,编译器允许

放弃创建类似的临时值并直接初始化为

对象。他们是怎么做到的?我不知道。检查汇编代码

你可能会发现大多数成员函数已经内联了
并且初始化直接进入对象

没有复制。


值得一提的是,虽然允许编译器在某些情况下跳过临时创建

的可能性,但是/>
仍然存在。例如,如果你声明你的类T private的复制构造函数,那么即使使用devc ++

,代码也不应该编译,因为无法复制(即使编译器可以创建

代码,不需要创建副本。


V



I think both are OK. During initialisation, the compiler is allowed
to forgo creation of a temporary like that and initialise directly into
the object. How they do it? I don''t know. Examine the assembly code
and you will probably find out that most of the member functions have
been inlined and the initialisation goes directly into the object
without copying.

May be worth to mention that while compiler is allowed to skip the
creation of a temporary in certain contexts, the possibility should
still exist. For example, if you declare the copy constructor for
your class T private, the code shouldn''t compile even with devc++
since the copy cannot be made (even though the compiler can create
code that doesn''t require creation of a copy).

V


* cfvis@gmail.com
[snip example] 如果它不是bcb,为什么?
[snip example]
anyway, i want to know which is correct, i mean, std compliant.
if it''s not bcb, why?




作为一个对Victor'的另一种解释,你可以选择考虑

这主要是关于复制构造函数,而不是临时工。


复制构造函数是只有成员函数需要做一个

的事情而且只有一件事:将参数复制到当前

待构建的对象中。


允许编译器假定复制const ructor做了它所应该的,而不是更多,而不是更少。在此基础上 - 考虑到您在复制构造函数中放置的实际代码,没有

-

编译器可以替换或删除调用,如果它离开了最终效果

不变。因此,如果复制构造函数执行的操作超出了它的预期值,那么这些操作就不能保证执行。


因此,任何C ++问题是要求你计算复制数量

构造函数调用是否有问题... ;-)


尝试优化复制构造函数调用。通常

最简单的代码将由编译器很好地优化,那些darned

复制操作被删除。但是聪明代码最终可能没有优化。


-

答:因为它弄乱了人们通常阅读文本的顺序。

问:为什么这么糟糕?

A:热门发布。

问:usenet和电子邮件中最烦人的事情是什么?



As an alternative explanation to Victor''s, you might choose to think about
this as primarily being about copy constructors, not temporaries.

A copy constructor is the only member function that is required to do one
thing and one thing only: to copy the argument into the current
to-be-constructed object.

The compiler is allowed to assume that a copy constructor does what it''s
supposed to, not more, and not less. And on that basis -- without
considering the actual code you''ve placed in in a copy constructor -- the
compiler can replace or remove calls if that leaves the final effect
unchanged. So if a copy constructor does something more than it''s supposed
to, then those actions are not guaranteed to be executed.

Thus, any C++ questionnare that asks you to count the number of copy
constructor calls is questionable... ;-)

And so are attempts at optimizing away copy constructor calls. Typically
the simplest code will be optimized very well by the compiler, those darned
copy operations removed. But "clever" code can end up with no optimization.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?


Alf P. Steinbach写道:
Alf P. Steinbach wrote:

编译器可以假设复制构造函数做了什么
它应该,而不是更多,而不是更少。并且在此基础上 -
而不考虑您在副本构造函数中放置的实际代码 - 如果
保持最终效果不变,编译器可以替换或删除调用。因此,如果复制构造函数确实比它应该的更多,那么这些操作将无法保证执行。

The compiler is allowed to assume that a copy constructor does what
it''s supposed to, not more, and not less. And on that basis --
without considering the actual code you''ve placed in in a copy
constructor -- the compiler can replace or remove calls if that
leaves the final effect unchanged. So if a copy constructor does
something more than it''s supposed to, then those actions are not
guaranteed to be executed.




我认为这仅适用于RVO和NRVO。在其他情况下,

编译器必须执行所有复制构造函数的

副作用等。如果它多次调用复制构造函数,

然后它必须多次做副作用。



I think that only applies to RVO and NRVO. In other cases,
the compiler must execute all of the copy constructor''s
side effects etc. If it calls the copy constructor multiple times,
then it must do the side effects multiple times.


这篇关于哪个是正确的?〜关于临时对象〜的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆