Anyway, this means that a user of a class doesn't
know if a copy constructor will be called unless he/she knows if
the mutator has been explicitly overloaded. Simply unacceptable.
I don't think it's unacceptable. When the copy constructor gets
called is the business of the programmer who wrote the class. If the
class writer wrote the class well, then the user of the class doesn't
have to concern him/herself with when the copy constructor gets called
or if a mutator has been explicitly overloaded.
Consider the Math::BigInt package. Over the years, there have been
different implementations of this class. Old versions of Math::BigInt
would autogenerate certain mutators (like "++" and "--"), but the
newest version explicitly overloads them (for efficiency's sake).
Calls to Math::BigInt's copy constructor will happen in one version
where it will not happen in the other. Yet the output is the same,
meaning that a programmer that uses Math::BigInt does not need to know
about Math::BigInt's internals like when the copy constructor will be
called or when a mutator has been explicitly overloaded. There is
nothing unacceptable about this.
Now, this is just wrong, at least in my environment - page 354:
"The ++$a operation can be autogenerated ... However, this does not
trigger the copying behavior that a real ++ operator would."
My ++ is autogenerated. If it did NOT cause copying then $a == $b
after $a = $b; ++$a; Nope, $a is one more than $b when I run this code.
Likewise, again on page 357:
"$copy = $original; $copy = $copy + 1;
then no copying occurs ..."
Again, $copy is one more than $original, so copying certainly did occur.
No, you are mistaken. Copying DID NOT occur. Examine the
following lines carefully:
$a = $b;
++$a;
When the '++' operator is autogenerated, these lines are equivalent
to:
$a = $b;
$a = $a + 1;
which DOES NOT call the copy constructor. Instead, the function used
for overloading the '+' operator is called, which normally creates a
new object, populates that object from $a and 1, then returns that new
object, which then gets assigned to $a WITHOUT ever modifying $b. In
other words, no copy of $b was every made or needed (which is why I
said that you are mistaken when you claim that copying certainly did
occur).
Confusing? A little. That's exactly why I posted a write-up
explaining this exact issue. I even posted the title of this write-up
("Regarding copy constructors and mutators") to you, and even included
a link to it. It seems like you didn't read it, so I invite you to
read it again so that your confusion about this subject can be cleared
up. In case you missed the link the first time around, here it is
again:
http://groups.google.com/[email protected]
And if you want the exact excerpt that deals with this topic
(without having to look for it), here it is (paraphrased to fit your
example):
=== Beginnining of excerpt ===
The line:
++$a;
was treated as if it was:
$a = $a + 1;
making it so that the function used for '+', and not for '++', was
used. The
function used for '+' does NOT mutate (or change) any parameter passed
in. Instead, that method creates a new object, modifies its value,
and returns that instance. This mutates the new object but it doesn't
affect either of the values passed in. Because of this, '+' isn't
considered by Perl to be a mutator, so it will not call the copy
constructor (and will not give an error if a copy constructor doesn't
exist). It just simply creates a new object from $a and 1 and assigns
it back to $a, making $a lose its original object reference.
CLARIFICATION:
If '+=' is used on a shared reference when '+=' is OVERLOADED, it WILL
call the copy constructor. But if it is AUTOGENERATED (from '+'), it
WILL NOT call the copy constructor, because '+' has no need for one.
The same goes for '++'. If it's not overloaded, Perl is smart enough
to autogenerate by converting "$a++" to "$a = $a + 1" (which doesn't
need the copy constructor) to give you exactly what you'd expect.
=== End of excerpt ===
Basically, what Anno Siegel wrote in an earlier post was absolutely
correct:
So unless you plan to overload mutators, don't worry about it at all.
(There is nothing unacceptable about that.)
Maybe this mess will be fixed in Perl 6. Otherwise, there's always Java -
no such thing as a copy constructor, and no operator overloading.
Maybe this "mess" will be understood when you get around to reading
the write-up I posted (intended for the Perl community and anyone
confused (like I was) about "Copy Constructor Crazyness"). You are
one of the people I posted that write-up for, so please read it before
criticizing this aspect of Perl again.
Hopefully this will clear the issue for you.
-- Jean-Luc