"I also think that there is a real problem with
the way classes are defined
in C++ and this is a problem which really does impact design. The problem is
that you are forced to define the private data members and functions at the
same time as the public ones. This is OK for the trivial C++ examples you
see in textbooks but as soon as you REALLY want to hide the private
information you end up defining the class to have a single private void
pointer which gets something allocated to it in the implementation. This is
basically the same thing you do when doing OO programming in C, so where is
the benefit of C++?"
--
You are not forced to define the private data members and functions at the
same time as
the public ones in C++. The way to handle this is to put the public
interface in a pure
virtual class:
class animal
{
public:
virtual int legs() = 0; // returns number of legs the animal uses when
moving around
};
and then derive from that interface:
class dog : public animal
{
public:
int legs() { return 4; }
};
i love C++. i think its one of the best things ever. but i happen to
agree with Erik. the solution proposed by martijn doesn't scale well,
and doesn't really address the issue in a comprehensive way. it
requires one pure virtual class per distinct set of private members,
for a start.
the kinds of problems i have with C++ stem from the fact that you
cannot mark a section of protected members as accessible from only a
particular set of friends. the only way to say "only class Foo can
access these member (functions)" is to create a separate class, make
Foo a friend of that class, and then inherit from it.
this gets really messy really soon. the editor object in Ardour
contains many distinct sets of functionality that i would really like
to partition. i could create a set of discrete classes that cover each
aspect of the functionality, and then do MI from all of them. the
problem is that is each one of these aspects *internally* needs to
know about the others, which now means that they each have to be
friends of each other. so what's the point? i'd end up with something
ludicrous like:
class EditorFoo {
...
protected:
friend class EditorThis;
friend class EditorThat;
friend class EditorTheOther;
...
friend class ObjectThatInteractsWithEditorFoo;
...
};
...
class Editor : public EditorFoo, EditorThis, EditorThat,
EditorTheOther .... {
}
which is really no help at all. the other alternative is to use HAS-A
instead of IS-A, and its even worse. we end up with lots of code like:
editor->foo->...
editor->that->...
editor->theother->...
all i'd really like it to be able to say:
class Foo {
protected:
/* scope A */
friend class Bar;
...
protected:
/* scope B */
friend class Baz;
...
};
such that Bar can only access stuff within "scope A" and Baz can only
access stuff in "scope B". that is, access control keywords
("private", "protected", "public" define access scopes).
right now, a
friend class declared anywhere within the class declaration is a
friend, period.
none of this helps with the problem erik identified. i would really
love a C++ that did this:
class Foo {
public:
... stuff ...
private:
<some tokens that meant something like #include>
};
and then in other files, you would do:
#use "foo.h"
or
#implementation "foo.h"
or something like that. the first one would just bring in the public
declarations, and its what you'd use when you're calling or creating
Foo objects. the second one would be used in the definitions for the
member functions of Foo, and hence would almost certainly be limited
to "foo.cc".
note that the private stuff would be in a file that looked just like
the class declaration, but had no public (and protected?)
declarations. in other words, the class declaration it includes is
implicitly 100% private, but it can include header files that are
necessary for the private declarations.
just dreaming.
--p