On Sunday, July 29, 2012 9:30:30 AM UTC+1, (unknown) wrote:
> W dniu sobota, 28 lipca 2012 23:15:15 UTC+2 użytkownik Victor Bazarov napisał:
> > On 7/28/2012 2:23 PM,
david...@o2.pl wrote:
[...]
> The above text is taken from "The C++ Programming Language",
> Seventh Edition, chapter 11.6 (Operator overloading: Large
> objects). I had that book before my eyes when I was writing my
> post. But it it is not rewritten a character to a character -
> I have a polish edition.
Don't. Regretfully, translations of technical books are almost
always miserable, and frequently misleading. Stroustrup is one
of the rare authors who understands the problem, and does what
he can to fix it, when he is made aware of it. But globally,
you're better off struggling in English with the original. You
won't have to deal with misleading translations, and when you do
post a question in an English speaking forum, you'll be able to
use the correct vocabulary, instead of trying to guess the
original word that the translator translated with whatever in
your language. And of course, the more you read in English,
the less you'll have to struggle.
(I really regret having to give this advice, because I think you
should be able to use your own language. But the reality is
that you can't.)
> >(1) You cannot return a reference to an automatic
> > object because by the time you get to use that reference, the object has
> > been already destroyed.
> Understand I things proper that it means that in the situation
> in which I have a variable which was declared in method m() I
> can not return a reference to that object? (It seems to me
> that more complex situations could lead to such error but that
> example has only show about what the problem is).
I think you need some clarification with regards to the language
you're using. All *objects* have a specific lifetime. (A
variable is a name bound to an object.) If you define a
non-static variable with local scope (within a block of code),
the object has something known as "automatic" lifetime, which
means it ceases to exist when the name goes out of scope.
(Unless, of course, the variable has reference type, in which
case, with one major exception which doesn't concern us here, it
has no effect on the object lifetime.)
A reference is not an object, but creates another way of
referring to an existing object. If the lifetime of the
reference exceeds that of the object, you have a dangling
reference. Which is undefined behavior---another way of saying
that anything might happen.
> >(2) You cannot return a reference to a static
> > object inside the op+ function because the function could be used more
> > than once in the same expression, and hence needs to be safely re-entrant.
> OK. But how returning the reference to the static object can
> make that re-entrant will not be safe?
In more complicated expressions, like "(a+b) * (c+d)", the
return value of "a+b" and of "c+d" refer to the same object. If
the two return values are supposed to have different values, one
of them will have been overwritten when you get to the *
operator.
> I want to know if returning a reference make it possible to
> improve an efficiency of calculations in instructions like:
> c=a+b;
It might, or it might not. In the general case, if copying a
Matrix is expensive, it probably will improve efficiency. At
the cost of giving incorrect results in more complicated
expressions.
> In other words: if we have instructions:
> c=a+b; //operator+ returns by a value
> f=d+e; //operator+ returns by a reference
> will one of those more efficient than other? For me it seems
> that not. In fist case return instruction inside operator+
> will make that one copy of object will be created. When the
> assignment will be executed a next copy has not be created
> because a+b is temporary so we can use it directly (and I
> think that every good compiler will not make that unnecessary
> copy). In second case a value is returned by a reference so
> object is not copied here. But copy has to be executed in
> order to make the assignment possible.
The assignment will still copy. On the other hand, the return
value will not be copied from any local variable.
Most compilers today implement some form the return value
optimization, which will avoid the copy in well written code.
(In at least one compiler, "well written code" means no more
than a single return statement in the function.)
> So in both cases one copy is created. So there is no reason
> for which one version should be more efficient than other. Am
> I right?
Without the return value optimization, return by value would
result in a copy in the function; the return value will be
copied from a local variable or a temporary into where ever the
compiler puts class type return values. (The memory used for
local variables typically disappears when you return from the
function.) The return value optimization means that this copy
is suppressed.
[...]
> > > Later, Stroustrup has given an example of the technique about which
> > > he has said that it causes that a result is not copied:
[...]
> const int max_matrix_tem = 7;
> Matrix& give_matrix_tem() {
> static int nbuf = 0;
> static Matrix buf[max_matrix_tem] nbuf = 0;
There's still too much on the preceding line.
> if (nbuf==max_matrix_tem) nbuf = 0; //missed line
> return buf[nbuf++];
> }
> That conception (using a buffer of static objects) is still
> not very clear for me. What is a reason for which operator+
> know that give_matrix_tem will give him an object which it
> that operator really needs?
Don't worry about it. It's an advanced technique, to be learned
only after you've mastered the basic lifetime issues. The basic
rule is:
-- return a reference when you want to allow access to data
held by your object (e.g. something like the operator[] on a
vector).
-- return a value in all other cases.
-- pass class types by reference to const, all other types by
value.
-- and don't use references anywhere but in the above cases.
That's sufficient for all but the most advanced programmers. (I
can't remember the last time I did anything else, and I've 30
years experience in C++, much of it in very low level,
performance oriented code.)
--
James