Cy said:
This is true but sort of unavoidable. Sooner or later you will want to get
some sort of extended functionality and you only have two choices: derive a
new class with the member function you want, or just write another function:
Well, that makes me wonder if having a special syntax for calling
member functions is actually a good thing. After all, why should it
matter to the user of the class if the operation on an object is
defined by the class or by some later code? Combining the idea of
"requires access to class internals," "is part of the class's
interface" and "is an operation on objects of the class" into one
syntax is, perhaps, confusing.
I belive in the Dylan language, obj.meth(arg) is just syntactic sugar
for meth(obj, arg) , which strikes me as quite an attractive design (in
Dylan, you define a function which does dynamic dispatch on the types
of its arguments outside of a class definition).
This is certainly not what I would call breaking encapsulation. Actually I
don't see the problem here at all.
Whether a function needs access to the internals of a class depends on
the implementation, no? A maybe interesting example is a class with two
methods, each of which can be implemented in terms of the other; thus,
which you make access the class internals is a matter of choice. If you
make one a member function and one a non-member, you're exposing this
choice in the interface, which sounds like breaking encapsulation to
me. Certainly, if you later decide to change your implementation
(perhaps implementing function A in terms of function B turns out to be
more efficient than the other way round), making one a member and the
other a non-member will cause you problems.