Re: extending c++ classes and enumerations
James Kanze skrev:
But you still haven't given a concrete example of exactly what
benefits you're referring to, and what C++ in particular offers
to provide those benefits.
To put it simply, I need to write less code in C++ than I would do in
C. C++ provides syntax short-cuts. I'm very lazy, and if there are
statement that make initialization, error checking, operands, etc into
simplier expressions and statement, I don't mind.
In C, I write
extern struct button *btn;
int foo_button(struct drag_session *di) {
struct drag_data dd;
drag_data_init(&dd);
if (drag_data_set_session(&dd, di) < 0)
return -1;
if (drag_data_copy_data(&dd, button_get_data(btn)) < 0)
return -1;
// ...
if (drag_begin(di, &dd) < 0) {
void *ptr = drag_data_get_data(&dd);
if (ptr != NULL) free(ptr);
if (drag_data_release(&dd) < 0)
; // ignore errors from release
}
};
Besides this soup, there may be ten other function doing similar work.
In C++, I use classes and templates resulting in all ten functions
becomes reduced to one function with tree lines:
class DragSession {
// prerequisites: class Responder implements getData()
template<typename Responder>
void foo(Responder &responder) throws(DragException) {
DragData dd(responder.getData());
dd.setSession(this);
beginDrag(dd);
}
};
This is something i felt beeing lexical (or syntaxical) benefits!
I don't have the complete implementation in my head, but from
what I remember, most of that "extra code" is in (private)
member classes. And of course, the implementation of
basic_string doesn't hesitate to make use of lower level
abstractions which are available (e.g. atomic_add, or whatever
the name is).
And I'm not sure what you're trying to get at. The GNU
implementation of basic_string most obviously doesn't need the
possibility to extend classes---the proof is that they
implemented it without implementing this ability.
Ok, then you could consider another scenario where a third-party
library "libfoo" delivers classes for say data-base management. The
vendor doesn't utilize own container classes, but neither use ANSI
standard classes. However, By using template mechanism the library will
be independend of what e.g. string implementation is used, the only
requirements is that the string model implements certain kind of
methods
/*
// Unfortunately, the vendor choosed java.lang.String naming style
// not std::string names.
model String {
String(const String &lhs);
String &charAt(int index);
int compareTo(const String &lhs);
int length();
// ...etc
};
// There will be similar function prerequisites for
// Arrays, Maps, Lists, etc.
*/
template<class String> Query { ... };
template<class String, ...> Database { ... };
(The C++ template mechanism where parameter's prerequisites is not
fulfilled, is catched by the compiler.)
Now, we decide to use ANSI C++ containers in our program. Since the
libfoo expects java.lang.String names, we must sub-class std::string
and add those java named methods. This is great but then we use another
library "libbar" which also use a sub-class of std::string; the types
becomes orthogonal. Thus, even if they derives from the same base
class, strings comming from libfoo needs to be translated to libbar
strings, or vice versa, an O(n) operation.
The statement "the encapsulated code isn't part of the real
encapsulation" suggests that you're thinking along the lines of
something like the code in the StringUtils.hh file of
http://kanze.james.neuf.fr/doc/en/Text/html/index.html. (The
actual code can be found at
http://kanze.james.neuf.fr/code-en.html.) But there again, the
possibility to extend a class obviously isn't needed, since the
code exists, despite the lack of this possibility. Allowing the
extension of the class would have two effects on this code:
1. it would allow the user to write s.trim(), rather than
trim(s), and
2. it would allow the actual code of trim() to access the
private implementation of basic_string, and thus violate the
invariants of basic_string.
Point one could easily be handled by a simple extension allowing
the use of member function syntax for free functions (and why
not, the inverse as well); if such a proposal has never been
made, I suspect that it is because no one has really felt that
this was a problem which needed solving.
Most peoples would probably add free functions (prefixed with the
namespace and class name to avoid return ambiguity) or sub-class the
original class. That's okay, but then your function may become
incompatible with other lexical or syntaxical benefits with C++, e.g.
member function pointers. Only because it has never been proposed,
doesn't mean it is not needed.
By the way, a member function-like syntax for free functions is already
semi-implemented. Adding
namespace my { class object { ... }; }
std::ostream &operator<<(ostream &rhs, my::object &lhs) { ... }
could also be achieved by adding a member function to std::ostream. :-)
I don't see your point (and I haven't seen Ondrej's posting
yet), but derivation does NOT allow accessing private members.
That is the key point. The fact that a class is closed is a
basic principle in C++, and the basis of C++'s support for
encapsulation. Remove it, and there is no fundamental
difference between classes and namespaces.
That would be another possibility if namespace names could be combined
with class names to put constants and functions under its label scope.
But will free function automatically become class' member function,
then?
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]