> But value semantics add lots of problems: copy constructors, overloading
> the assignment operator, the need for separate reference variables. Each
> of which is a potential source for subtle bugs. And what advantages
> do you get in return?
The nice thing about C++ is that you can use reference semantics or value
semantics depending on which makes sense. Languages with reference semantics
and all virtual functions do make life easier at first. C++ lets you code
that way and most people do for most classes.
However, when you want a class to behave like an elementary type value
semantics are indispensable. Imagine implementing complex numbers or
quatertions or 3-vectors with reference semantics. In order to be safe you
would have to make them immutable. This eliminates expressive syntax such as
"A.z = 0." and replaces it with things like "A = vector(A.x,A.y,0.)" or worse.
As for copy constructors, etc., these aren't any harder than writing a copy()
method in another language and for objects that don't allocate memory they
are synthesized automagically by the compiler. Also, any bugs in these
methods are easy to debug with a simple test code, whereas aliasing problems
caused by reference semantics can be anywhere.
> True, but I have the impression that this is considered "against the
> spirit" of the language and therefore rarely done. And it certainly
> doesn't make a program easier to understand if there are both types
> of semantics around.
Reference semantics and reference-counted storage in C++ is rarely done, but
I don't think its a moral issue. I think it is unfamiliar and is seldom
really necessary, so not many people bother.
I'll agree that mixed semantics make code confusing, but every language uses
value semantics for elementary types. Therefore, C++ makes the different
semantics explicit by defaulting to value semantics unless you either
explicitly use pointers or go though the work of using reference-counted
storage (but don't make it act like value semantics).
My ideal C++ matrix system would use pointers and reference-counted storage
to eliminate copying on assignments, but would automatically create a copy if
you tried to modify a matrix which shared its data. Then you could write:
E(10,12) = 0.;
A = B = C = D = E; // no new storage allocated
C(10,12) = 1.; // first copied into new storage for C
C(2,4) = 5.; // no new storage allocated
assert( B(10,12) == 0. ); // no new storage allocated
But if you really wanted aliasing or reference semantics you could use
pointers or references to make it explicit. This is why I love the power of
C++.
> compatibility requirement, there are other OO languages (e.g. Eiffel
> or Oberon) which are much simpler and cause much fewer surprises.
True.
-Jim Phillips
jim@ks.uiuc.edu
This archive was generated by hypermail 2b29 : Wed Feb 20 2002 - 03:20:05 EST