>"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