以价值回归(这里我们再去!) [英] Returning by value (here we go again!)

查看:36
本文介绍了以价值回归(这里我们再去!)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



AnyClass Blah()

{

AnyClass便便;


返回便便;

}

众所周知,在上面,编译器有权:


1)创建对象" ; poo"

2)创建poo的副本

3)销毁poo

4)返回副本< br $>




1)创建对象poo

2)返回poo

由于第一个选择,无论是否制作副本,副本

构造函数必须是公开的。


所有,我认为如果我们在C ++中有一个新类型的返回

语句就会很方便,这个语句使得实际对象返回

(没有复制)因此复制构造函数不需要公开...允许以下类似的东西:


std :: ostream Blah()

{

std :: ostream poo;


return_actual_object poo;

}

无论如何......


为实现这一目标,我正在使用auto_ptr的那一刻,如下:


auto_ptr< AnyClass> Blah()

{

auto_ptr< AnyClass> poo(新AnyClass);


返回poo;

}


int main()

{

auto_ptr< AnyClass> const& milk = Blah();


//现在可以随意使用它!

//如果我想要参考语法:


AnyClass const& cheese = * milk;


cheese.MemberFunction();

}

编译器仍然可以选择复制auto_ptr ......但是它比复制整个物体要好得多b $ b!另外,我可以返回

" std :: ostream"按价值......(有点儿!)。


AAnnyywwaayy ...今天看一下C ++参考我有点震惊

看:


basic_string :: substr

basic_string substr(size_type off = 0,

size_type count = npos)const;

成员函数返回一个对象,其受控序列是

的副本,最多可计算从关闭位置开始的受控序列的元素。

它按值返回! AAAAAAaaahhhhhhhh! throw Inefficiency(); !

-JKop


AnyClass Blah()
{
AnyClass poo;

return poo;
}
As we all know, in the above, the compiler is entitled to:

1) Create the object "poo"
2) Create a copy of "poo"
3) Destroy "poo"
4) Return the copy

or

1) Create the object "poo"
2) Return "poo"
On account of the first choice, whether a copy is made or not, the copy
constructor must be public.

First of all, I think it would be handy if we had a new type of "return"
statement in C++, one which makes it so that the actual object is returned
(no copy made) and as such the copy constructor wouldn''t need to be
public... allowing the likes of the following:

std::ostream Blah()
{
std::ostream poo;

return_actual_object poo;
}
Anyway...

To achieve this, at the moment I''m using auto_ptr, as follows:

auto_ptr<AnyClass> Blah()
{
auto_ptr<AnyClass> poo( new AnyClass );

return poo;
}

int main()
{
auto_ptr<AnyClass> const &milk = Blah();

//now work with it as I please!
//and if I want reference syntax:

AnyClass const& cheese = *milk;

cheese.MemberFunction();
}
The compiler still has the choice of copying the auto_ptr... but it''s a hell
of a lot better than copying the entire object! Plus, I can return an
"std::ostream" by value... (kind of!).

AAnnyywwaayy... looking through a C++ reference today I was sort of shocked
to see:

basic_string::substr
basic_string substr(size_type off = 0,
size_type count = npos) const;
The member function returns an object whose controlled sequence is a copy of
up to count elements of the controlled sequence beginning at position off.
It returns by value! AAAAAAaaahhhhhhhh! throw Inefficiency(); !
-JKop

推荐答案

JKop写道:


首先,我认为如果我们在C ++中使用一种新的返回语句会很方便,它会使实际对象返回
(没有复制品)因此复制构造函数不需要公开......允许以下类似:

std :: ostream Blah()
{
std :: ostream poo;

return_actual_object poo;
}


问题不在于此。

问题是禁止复制流对象。


至于你的建议。

现在我们有一个简单的规则:每个本地对象都会在函数的

末尾被销毁。你的建议会例外。

那个本地对象的范围是什么?换句话说:什么时候

它会被摧毁?

无论如何...

要做到这一点,目前我正在使用auto_ptr,如下:

auto_ptr< AnyClass> Blah()
{
auto_ptr< AnyClass> poo(新的AnyClass);

返回poo;
}


罚款。换句话说:您动态分配对象

并要求调用者释放它。精细。为了给呼叫者提供一些帮助,你给它打了一个信封。另外

罚款。


[snip]
编译器仍然可以选择复制auto_ptr ...但它是地狱<比复制整个对象要好得多!另外,我可以返回一个
std :: ostream按价值...(有点!)。

AAnnyywwaayy ...今天透过C ++参考我有点震惊
看:

basic_string :: substr
basic_string substr(size_type off = 0,
size_type count = npos)const;
成员函数返回一个对象,其受控序列是
的副本,最多可计数受控序列的元素从关闭位置开始。

它按值返回! AAAAAAaaahhhhhhhh! throw Inefficiency(); !


First of all, I think it would be handy if we had a new type of "return"
statement in C++, one which makes it so that the actual object is returned
(no copy made) and as such the copy constructor wouldn''t need to be
public... allowing the likes of the following:

std::ostream Blah()
{
std::ostream poo;

return_actual_object poo;
}
The problem with this is not the return.
The problem is that copying a stream object is forbidden.

As for your suggestion.
Now we have a simple rule: Every local object gets destroyed at the
end of the function. Your suggestion would make an exception to that.
What would be scope of that local object? In other words: when
does it get destroyed?

Anyway...

To achieve this, at the moment I''m using auto_ptr, as follows:

auto_ptr<AnyClass> Blah()
{
auto_ptr<AnyClass> poo( new AnyClass );

return poo;
}
Fine. In other words: You dynamically allocate the object
and ask the caller to free it. Fine. In order to help
the caller somewhat, you put an envelope around it. Also
fine.

[snip]
The compiler still has the choice of copying the auto_ptr... but it''s a hell
of a lot better than copying the entire object! Plus, I can return an
"std::ostream" by value... (kind of!).

AAnnyywwaayy... looking through a C++ reference today I was sort of shocked
to see:

basic_string::substr
basic_string substr(size_type off = 0,
size_type count = npos) const;
The member function returns an object whose controlled sequence is a copy of
up to count elements of the controlled sequence beginning at position off.

It returns by value! AAAAAAaaahhhhhhhh! throw Inefficiency(); !




你不应该感到震惊。


string a =" abcd";

string b = a.substr(2)+" xyz";


为了使其正常工作,没有其他选择可以返回副本。

返回值优化负责其余部分。


-

Karl Heinz Buchegger
kb ****** @ gascad.at


文章< Ar *** ****************@news.indigo.ie>,

JKop< NU ** @ NULL.NULL>写道:
In article <Ar*******************@news.indigo.ie>,
JKop <NU**@NULL.NULL> wrote:
首先,我认为如果我们在C ++中有一个新类型的返回语句,它会很方便,这使得它可以使返回实际对象
(没有复制)因此复制构造函数不需要公开......允许以下类似:

std :: ostream Blah()
{
std :: ostream poo;

return_actual_object poo;
}


I同意,至少部分同意。这可以通过移动语义来实现:

http://www.open-std.org/jtc1/sc22/wg...004/n1690.html
http://www.open-std.org/jtc1 / sc22/wg...2002/n1377.htm


遗憾的是,它不属于C ++的一部分。如果你想看看

移动语义成为C ++的一部分,请确保你在C ++委员会的国家代表知道这一点。


具有非cv合格汽车存储的可移动但不可复制的类型

应该可以通过函数的值返回。例如,请参阅:

http://www.open-std.org/jtc1/sc22/wg...77.htm#Moving%

20from%20local %20values


std :: streams可以移动,并且保持不可复制。

无论如何......

实现这一点,目前我正在使用auto_ptr,如下所示:

auto_ptr< AnyClass> Blah()
{
auto_ptr< AnyClass> poo(新的AnyClass);

返回poo;
}
int main()
{
auto_ptr< AnyClass> const& milk = Blah();

//现在可以随意使用它!
//如果我想要参考语法:

AnyClass const& ; cheese = * milk;

cheese.MemberFunction();
}


< nod>今天的解决方法很丑陋。

AAnnyywwaayy ...今天看一下C ++参考我有点震惊
看看:

basic_string :: substr
basic_string substr(size_type off = 0,
size_type count = npos)const;
成员函数返回一个对象,其受控序列是
的副本,最多可计入元素的数量从关闭位置开始的受控序列。

按值返回! AAAAAAaaahhhhhhhh! throw Inefficiency(); !
First of all, I think it would be handy if we had a new type of "return"
statement in C++, one which makes it so that the actual object is returned
(no copy made) and as such the copy constructor wouldn''t need to be
public... allowing the likes of the following:

std::ostream Blah()
{
std::ostream poo;

return_actual_object poo;
}
I agree, at least partly. This can be achieved with move semantics:

http://www.open-std.org/jtc1/sc22/wg...004/n1690.html
http://www.open-std.org/jtc1/sc22/wg...2002/n1377.htm

which unfortunately is not part of C++ today. If you would like to see
move semantics become part of C++, make sure your national
representative on the C++ committee knows that.

Movable, but non-copyable types with non-cv qualified auto storage
should be returnable by value from functions. For example see:

http://www.open-std.org/jtc1/sc22/wg...77.htm#Moving%
20from%20local%20values

std::streams could be made movable, and remain non-copyable.
Anyway...

To achieve this, at the moment I''m using auto_ptr, as follows:

auto_ptr<AnyClass> Blah()
{
auto_ptr<AnyClass> poo( new AnyClass );

return poo;
}

int main()
{
auto_ptr<AnyClass> const &milk = Blah();

//now work with it as I please!
//and if I want reference syntax:

AnyClass const& cheese = *milk;

cheese.MemberFunction();
}
<nod> Today''s workarounds are ugly.
AAnnyywwaayy... looking through a C++ reference today I was sort of shocked
to see:

basic_string::substr
basic_string substr(size_type off = 0,
size_type count = npos) const;
The member function returns an object whose controlled sequence is a copy of
up to count elements of the controlled sequence beginning at position off.

It returns by value! AAAAAAaaahhhhhhhh! throw Inefficiency(); !




substr来构造另一个字符串,那么一个好的编译器可以优化掉这个副本。但如果它使用substr将

分配给现有字符串,则仍会创建临时字符。


移动语义会更加可口。临时的

仍然可以创建,但随后它将被移除,而不是复制自




-Howard



A good compiler can optimize away this copy if the client is using
substr to construct another string. But if it is using substr to assign
into an existing string a temporary is still created.

It would be a lot more palatable with move semantics. The temporary
could still be created, but then it would be moved from, instead of
copied from.

-Howard




" JKop" < NU ** @ NULL.NULL>在消息中写道

新闻:Ar ******************* @ news.indigo.ie ...

"JKop" <NU**@NULL.NULL> wrote in message
news:Ar*******************@news.indigo.ie...

AnyClass Blah()
{
AnyClass poo;

返回poo;
}

我们都知道,在以上,编译器有权:1)创建对象poo
2)创建poo的副本
3)销毁poo ; 4)退回副本



1)创建对象poo
2)返回poo

或优化函数调用Blah并在函数调用的点上创建AnyClass对象。但是,这是否可以完成

并且有意义取决于具体情况。

由于第一个选择,无论是否制作副本,副本
构造函数必须是公共的。


嗯,这有什么问题。声明副本ctor

private / protected是一个成语,表示不能创建任何副本。

首先,我认为如果我们有一个新的话会很方便C ++中的return类型的语句,它使得实际的对象被返回
(没有复制),因此复制构造函数不需要是
公开......允许以下类似:

std :: ostream Blah()
{
std :: ostream poo;

return_actual_object poo;
}

正如Karl Heinz已经提到的那样,范围问题和自动的b $ b破坏是绝对有意义的。否则我们将进入需要进行垃圾控制的方向的C#,Java等方向。专业人士

GC本身就是一个话题。

无论如何......

为了达到这个目的,目前我正在使用auto_ptr,如下:

auto_ptr< AnyClass> Blah()
{
auto_ptr< AnyClass> poo(新的AnyClass);

返回poo;
}
int main()
{
auto_ptr< AnyClass> const& milk = Blah();

//现在可以随意使用它!
//如果我想要参考语法:

AnyClass const& ;奶酪= *牛奶;

cheese.MemberFunction();
}


所以你使用的指针具有可转让的所有权,但你是前往

你的代码混乱的方向主要是不必要的

这样的结构。通过适当的设计,这些东西应该很少需要b $ b。

编译器仍然可以选择复制auto_ptr ......但它是
hell比复制整个对象好多了!另外,我可以返回一个
std :: ostream按价值...(种类!)。


顺便说一句,不允许复制流。

AAnnyywwaayy ...今天通过C ++参考查看我有点震惊地看到:


basic_string :: substr
basic_string substr(size_type off = 0,
size_type count = npos)const;
成员函数返回一个对象,其受控序列为复制
最多可以计算从关闭位置开始的受控序列的元素。

它按值返回! AAAAAAaaahhhhhhhh! throw Inefficiency(); !

AnyClass Blah()
{
AnyClass poo;

return poo;
}
As we all know, in the above, the compiler is entitled to:

1) Create the object "poo"
2) Create a copy of "poo"
3) Destroy "poo"
4) Return the copy

or

1) Create the object "poo"
2) Return "poo"

or optimize away the function call to Blah and create the AnyClass object at
the point of the function call instead. However, whether this can be done
and makes sense depends on the context.

On account of the first choice, whether a copy is made or not, the copy
constructor must be public.
Well, what′s the problem with that. Declaring the copy ctor
private/protected is an idiom that signals that no copy can be created.

First of all, I think it would be handy if we had a new type of "return"
statement in C++, one which makes it so that the actual object is returned
(no copy made) and as such the copy constructor wouldn''t need to be
public... allowing the likes of the following:

std::ostream Blah()
{
std::ostream poo;

return_actual_object poo;
}

As Karl Heinz already mentioned there is the issue of scope and automatic
destruction, which makes absolutely sense. Otherwise we′re going into the
C#, Java etc. direction where garbage control ist needed. The pros & cons of
GC are a topic themselves.

Anyway...

To achieve this, at the moment I''m using auto_ptr, as follows:

auto_ptr<AnyClass> Blah()
{
auto_ptr<AnyClass> poo( new AnyClass );

return poo;
}

int main()
{
auto_ptr<AnyClass> const &milk = Blah();

//now work with it as I please!
//and if I want reference syntax:

AnyClass const& cheese = *milk;

cheese.MemberFunction();
}

So you′re using a pointer with transferable ownership but you′re heading in
the direction where you clutter your code with mostly unnecessary
constructions like that. With a proper design such things should rarely be
required.

The compiler still has the choice of copying the auto_ptr... but it''s a hell of a lot better than copying the entire object! Plus, I can return an
"std::ostream" by value... (kind of!).
BTW, copying streams is not allowed.

AAnnyywwaayy... looking through a C++ reference today I was sort of shocked to see:

basic_string::substr
basic_string substr(size_type off = 0,
size_type count = npos) const;
The member function returns an object whose controlled sequence is a copy of up to count elements of the controlled sequence beginning at position off.
It returns by value! AAAAAAaaahhhhhhhh! throw Inefficiency(); !




屏住呼吸;-)按照价值而不是参照的方式返回绝对是在这种情况下确定感觉,正如卡尔已经指出的那样亨氏。但是,我建议您阅读Scott Meyers的第23章Effective

C ++。


正如他所说:[引用]这一切归结为:当决定

返回一个引用并返回一个对象时,你的工作是制作

选择做正确的事情。让你的编译器供应商与

进行斗争,弄清楚如何让这个选择尽可能便宜 [quote]


Chris



Hold you breath ;-) Returning by value instead of reference makes absolutely
sense in this case, as already pointed out by Karl Heinz. However, I′d
suggest that you read the respective chapter 23 in Scott Meyers "Effective
C++".

As he says: [quote] "It all boils down to this: when deciding between
returning a reference and returning an object, your job is to make the
choice that does the right thing. Let your compiler vendors wrestle with
figuring out how to make that choice as inexpensive as possible" [quote]

Chris


这篇关于以价值回归(这里我们再去!)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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