Java Forum / General / July 2006
Java vs C++, A Newbie's perspective.
fiziwig - 02 Jul 2006 05:14 GMT I'm pretty new to Java, but with loads of C++ experience. Today I started working on a new ap just for fun and I was trying to decide whether to use C++ or Java.
After some fiddling around with both I came to an intersting conclusion, to wit:
Java makes the hard stuff easy, and the easy stuff hard. C++ makes the easy stuff easy and the hard stuff hard.
When will they invent a language that makes it ALL easy?!
Please tell me it's going to get better as I learn more Java, 'cause I REALLY like it, but it sure can be a pain at times. ;-)
--gary
Stefan Ram - 02 Jul 2006 05:37 GMT >Java makes the hard stuff easy (X-post and Followup-To set to comp.lang.java.advocacy.)
»Java books are usually about doing stuff. C++ books are mostly about not shooting yourself in the foot.« -- Bjorn Borud
»Memory management in multi-threaded applications is one of the biggest challenges C++ programmers face. It's a nightmare. All kinds of techniques and protocols have been developed to help make the task easier, but none of them work very well. At the very least they all require a certain discipline on the part of the programmer that is very difficult to maintain. And for complex pieces of code that are being worked on by more than one person it is very, very hard to get it right.
[Ron Garret now describes that a bug occurred, that has to do with multi-threading and memory management in C++.]
On top of that, this kind of bug is actually impossible to introduce except in a language with manual memory management like C++. In a language with automatic memory management like Java or Lisp the system automatically notices that the memory is still in use and prevent it from being reused until all threads were actually done with it. By the time this bug was found and fixed (...) I was a mental wreck, and well on my way to becoming a physical wreck as well. My relationship with my wife was beginning to strain. My manager and I were barely on speaking terms. (...) « -- Ron Garret
josh.s17@gmail.com - 02 Jul 2006 07:20 GMT Have you got any specific example of this. I think I know what you mean as I came from a C++ background as well.
> I'm pretty new to Java, but with loads of C++ experience. Today I > started working on a new ap just for fun and I was trying to decide [quoted text clipped - 12 lines] > > --gary fiziwig - 02 Jul 2006 07:26 GMT josh....@gmail.com wrote:
> Have you got any specific example of this. I think I know what you mean > as I came from a C++ background as well. The straight jacket I'm fighting with right now is trying to use a StringBuffer object as a string buffer.
I build a long working string from some input data and then output it to a file, then I want to start over with the next batch of input by emptying out the string buffer and putting the new stuff into it. In the process I'm doing loads of search and replace on the text in the StringBuffer, causing it to grow in length. But guess what, no replace,
replaceAll,...etc. methods in StringBuffer. What good is a string buffer without search and replace? So what do I do, shuffle the text back and forth between a String and a StringBuffer to do the search and
replace?
With my scant knowledge of Java I assumed there would be a setText method for StringBuffer to replace existing text with new text each time I'm ready to start a new batch. But nope. No such method. Nor is there a deleteText method for string buffer. In C++ I could write buffer[0]=NULL; and be done with it, but with a StringBuffer I guess I have to use the delete method for the whole length of the contents. Kind of a pain. So much power and so many blind spots where sorely needed methods just don't exist. The class should have been called StringAppender, 'cause that's all it knows how to do. And that's the one thing I DON'T need it to do for me.
So instead of being able to manipulate the data in place in a single re-usable buffer I have to create and discard new String objects right and left making the garbage collector have a nervous breakdown. It's enough to make me want to code my ap with a character array the old fashioned way.
--gary
Stefan Ram - 02 Jul 2006 07:31 GMT >StringBuffer, causing it to grow in length. But guess what, no replace, >replaceAll,...etc. methods in StringBuffer. What good is a string >buffer without search and replace? http://download.java.net/jdk6/docs/api/java/lang/StringBuilder.html#indexOf(java .lang.String) http://download.java.net/jdk6/docs/api/java/lang/StringBuilder.html#replace(int, int, java.lang.String)
>Nor is there a deleteText method for string buffer. http://download.java.net/jdk6/docs/api/java/lang/StringBuilder.html#delete(int, int)
For other similar operations see:
http://download.java.net/jdk6/docs/api/java/lang/StringBuilder.html http://download.java.net/jdk6/docs/api/java/lang/StringBuffer.html
Chris Smith - 02 Jul 2006 08:01 GMT > The straight jacket I'm fighting with right now is trying to use a > StringBuffer object as a string buffer. [quoted text clipped - 8 lines] > back and forth between a String and a StringBuffer to do the search and > replace? I have my complaints about Java, but it sounds like your problem has less to do with the language and more to do with not knowing the API, or apparently reading the API documentation. Do you have a copy of the API documentation? setLength(0) clears the contents, indexOf searches, and replace... well, replaces. You can even search with regular expressions if you like, although it's a bit of a longer way around because you lack the convenience functions from the String class. Nevertheless, StringBuffer implements CharSequence, so it can be used for regular expression searches just as well as anything else.
> In C++ I could write buffer[0]=NULL; and be done with it Wait a sec... You're supposedly writing code with char arrays in C++ instead of using the standard API std::string class? And then you say C++ makes easy things easy? That, I really don't understand... unless you consider not writing buffer overflows to be one of those things that are just supposed to be hard...
Next time you may want to take more time to learn what you're doing before you start blaming the tools.
 Signature Chris Smith - Lead Software Developer / Technical Trainer MindIQ Corporation
fiziwig - 02 Jul 2006 09:47 GMT > Next time you may want to take more time to learn what you're doing > before you start blaming the tools. > > -- > Chris Smith - Lead Software Developer / Technical Trainer > MindIQ Corporation True enough, and I will take it to heart. There's a LOT of classes to learn in Java, and being only a few days into it, I've got a loooong ways to go.
--gary
Frank van Schie - 02 Jul 2006 17:33 GMT >> Next time you may want to take more time to learn what you're doing >> before you start blaming the tools. [quoted text clipped - 6 lines] > learn in Java, and being only a few days into it, I've got a loooong > ways to go. Consider it a rule of thumb that, when you're trying to do something and think "This is too hard! Why didn't they make an object that actually does what people might want it to do!", there's a good chance they did, and it's elsewhere in the API.
I trust you do have the Java API docs[0] in front of you when you code?
[0]: http://java.sun.com/j2se/1.5.0/docs/api/ or http://java.sun.com/j2se/1.4.2/docs/api/
 Signature Frank
Thomas Hawtin - 02 Jul 2006 12:52 GMT >> In C++ I could write buffer[0]=NULL; and be done with it > [quoted text clipped - 3 lines] > you consider not writing buffer overflows to be one of those things that > are just supposed to be hard... The code looks just as valid if buffer was std::string instead of char*. (g++ complains about implicitly casting NULL to char, but IIRC NULL is defined to be 0 in C++. Character with ASCII code zero is properly known as NUL.)
#include <string> #include <iostream>
int main() { std::string str("My string"); str[0] = NULL;//'\0';// std::cout << str << std::endl; }
Might not do what you expect (possibly it is platform dependent).
Tom Hawtin
 Signature Unemployed English Java programmer http://jroller.com/page/tackline/
Dale King - 05 Jul 2006 09:32 GMT >> I build a long working string from some input data and then output it >> to a file, then I want to start over with the next batch of input by >> emptying out the string buffer and putting the new stuff into it.
> I have my complaints about Java, but it sounds like your problem has > less to do with the language and more to do with not knowing the API, or > apparently reading the API documentation. Do you have a copy of the API > documentation? setLength(0) clears the contents In general it is probably not a good idea to use setLength(0) to reuse a StringBuffer. In the past the JDK had code to optimize conversion from a StringBuffer to a String. The new String would actually not be a copy of the contents of the StringBuffer, but instead they would share the same char array. If after converting to a string you modified the StringBuffer, then the StringBuffer would do a copy for its own use so that it could modify it.
There would also be a problem with this sharing behavior with memory usage. The char array in the StringBuffer can be larger than the amount of text that it holds. You could for instance have a StringBuffer with a char array that is several K but only holds a few characters. If you did a toString then the String would then inherit this extra space.
By reusing the StringBuffer repeatedly you tended to accumulate extra space as the capacity of the StringBuffer would be whatever was the largest amount of text you had in it and you would then pass on this bloat to the strings you created.
Looking at the source, I don't think this is the case any more in 1.5, but is something to be aware of.
 Signature Dale King
Chris Smith - 05 Jul 2006 17:09 GMT > Looking at the source, I don't think this is the case any more in 1.5, > but is something to be aware of. I'm looking at the source, and it looks like this hasn't changed. I agree it's something to be aware of, and that reusing a StringBuffer unnecessarily is not the greatest idea. That said, if there's actually a *reason* to reuse the StringBuffer, such as if most of the content will be remaining the same, the problem is easily avoided by use of the new String(String) constructor.
 Signature Chris Smith - Lead Software Developer / Technical Trainer MindIQ Corporation
Dale King - 05 Jul 2006 18:35 GMT >> Looking at the source, I don't think this is the case any more in 1.5, >> but is something to be aware of. > > I'm looking at the source, and it looks like this hasn't changed. It most certainly looks like it has changed to me. When you call toString on a StringBuffer in 1.5 it makes a copy of the char array. Prior to 1.5, the String class would not get a copy but would get the actual char array in the StringBuffer and the StringBuffer would be marked so that a copy needed to be made before any modification.
I think with the advent of StringBuilder in 1.5 and the gotchas that this created they decided the optimization was no longer necessary.
> I > agree it's something to be aware of, and that reusing a StringBuffer > unnecessarily is not the greatest idea. That said, if there's actually > a *reason* to reuse the StringBuffer, such as if most of the content > will be remaining the same, the problem is easily avoided by use of the > new String(String) constructor. Actually, I don't think that would solve the issue. As I remember that would not eliminate the wasted space. That would just give you 2 String objects pointing at the same char array with wasted space. I believe you actually had to use substring in order to trim the unused char array space.
If you are using 1.5 it looks like reusing StringBuffer (and more likely StringBuilder) is not a problem. If you are using 1.4 or before you need to be careful and understand the gotchas.
I found an old thread on this topic:
http://groups.google.com/group/comp.lang.java.programmer/browse_thread/thread/e4 144e0c6ffbcfae?tvc=2
 Signature Dale King
Chris Smith - 05 Jul 2006 19:39 GMT > >> Looking at the source, I don't think this is the case any more in 1.5, > >> but is something to be aware of. [quoted text clipped - 6 lines] > actual char array in the StringBuffer and the StringBuffer would be > marked so that a copy needed to be made before any modification. You're right. I was confusing the (char[],int,int) constructor with the (int,int,char[]) constructor.
> > I > > agree it's something to be aware of, and that reusing a StringBuffer [quoted text clipped - 7 lines] > objects pointing at the same char array with wasted space. I believe you > actually had to use substring in order to trim the unused char array space. Actually, it's the opposite. The substring method does not copy the contents but just returns a new String object pointing to the same backing. The String(String) constructor does do the copy if the existing char[] is too big. If you look at the code there, it specifically checks whether the original String has a char[] that's longer than its effective length... and if so, it allocates a different char[] of the right size, and copies the relevant data into it.
(Notice that substring does use the String(int,int,char[]) constructor, which does NOT copy anything.)
 Signature Chris Smith - Lead Software Developer / Technical Trainer MindIQ Corporation
Moiristo - 02 Jul 2006 12:37 GMT > I'm pretty new to Java, but with loads of C++ experience. Today I > started working on a new ap just for fun and I was trying to decide [quoted text clipped - 12 lines] > > --gary This is what you are looking for:
http://www-instruct.nmu.edu/math_cs/tseethof/cprimer/
Moiristo - 02 Jul 2006 12:39 GMT > I'm pretty new to Java, but with loads of C++ experience. Today I > started working on a new ap just for fun and I was trying to decide [quoted text clipped - 12 lines] > > --gary Not directly on-topic, but this site compares java and c++ with each other:
http://www-instruct.nmu.edu/math_cs/tseethof/cprimer/
Timo Stamm - 02 Jul 2006 15:34 GMT Moiristo schrieb:
> Not directly on-topic, but this site compares java and c++ with each other: > > http://www-instruct.nmu.edu/math_cs/tseethof/cprimer/ There is an error on the page "Commonalities":
| The following line is acceptable to C++ but not to Java: | | if(x = y){//some instructions} | | Note carefully, that while the above line is acceptable to a C++ | compiler, it is almost always a mistake. Provided that x and y are boolean variables, the assignment is a boolean expression. The following code will compile in Java:
boolean x = true; boolean y = false; if (x = y) {}
A decent Java compiler however will issue a warning about a possible accidental assignment in place of a comparison.
I am missing a comparison between templates and generics, but I guess the pages are older than Java 1.5.
Thanks for the link, Timo
Moiristo - 03 Jul 2006 00:10 GMT > | The following line is acceptable to C++ but not to Java: > | [quoted text clipped - 9 lines] > boolean y = false; > if (x = y) {} You're right, the author should have mentioned that it does compile when both variables are booleans
> A decent Java compiler however will issue a warning about a possible > accidental assignment in place of a comparison. Sun's javac doesn't give any warning, not even in verbose/debug mode.
> I am missing a comparison between templates and generics, but I guess > the pages are older than Java 1.5. A teacher gave me the link when Java 1.5 wasn't released yet. I would say that generics are the same for both java and c++?
> Thanks for the link, np
Chris Uppal - 03 Jul 2006 10:08 GMT > I would > say that generics are the same for both java and c++? Not even remotely similar. The two systems only just barely overlap. Whatever you do, don't try to take C++ templates as a guide to Java generics.
-- chris
Timo Stamm - 03 Jul 2006 10:17 GMT Moiristo schrieb:
> I would > say that generics are the same for both java and c++? No, they are quite different. I think it is fair to say that C++ Templates are much more powerful than Java Generics.
Chris Smith - 03 Jul 2006 18:41 GMT > Moiristo schrieb: > > I would > > say that generics are the same for both java and c++? > > No, they are quite different. I think it is fair to say that C++ > Templates are much more powerful than Java Generics. I'd say that's a somewhat meaningless comparison. They have different purposes. The purpose of Java generics has to do with opening up the type system to allow basic uses of type polymorphism, but without the possibility of accidental type errors remaining uncaught. The purpose of C++ templates is to provide a more language-aware kind of macro facility. These are almost entirely unrelated purposes. The fact that they can both be used to provide general-purpose collection classes is almost a coincidence.
If you want a macro facility, then C++ templates are far more powerful, and Java generics are rather puny and pointless. If you want to express precise type constraints on expressions, then Java generics are far more powerful, and C++ templates don't actually even solve the problem at all but rather shove the problem off, refusing to even think about type- correctness until the macro expansion is done.
 Signature Chris Smith - Lead Software Developer / Technical Trainer MindIQ Corporation
Jeffrey Schwab - 03 Jul 2006 18:52 GMT >> Moiristo schrieb: >>> I would [quoted text clipped - 17 lines] > but rather shove the problem off, refusing to even think about type- > correctness until the macro expansion is done. No, you've misunderstood. C++ templates are not just glorified macros in any sense. They exist primarily to support compile-time polymorphism. And IMHO, they are far more powerful than Java generics, which just add a little compile-time type checking and automatic casting.
For the record, I have no interest in a which-language-is-better discussion. But the info you've given is just dead wrong.
Chris Smith - 03 Jul 2006 19:11 GMT > No, you've misunderstood. C++ templates are not just glorified macros > in any sense. They exist primarily to support compile-time [quoted text clipped - 3 lines] > For the record, I have no interest in a which-language-is-better > discussion. But the info you've given is just dead wrong. No, I haven't misunderstood at all. Perhaps if you explained why you disagree with my statement, we could have a productive discussion on the matter. I am missing that part of your reply, though.
If you don't agree, perhaps you'd like to explain how C++ templates provide anything powerful enough to express the equivalent of the following method signature with Java generics:
public void doSomething(List<? extends Auditable> events);
or perhaps the C++ equivalent of:
public class MyClass<T extends Comparable<T>> { ... }
You see? You can't do it. These are type system features, and C++ templates don't provide them. In fact, type-checking a program that uses a C++ template means expanding the template and then type-checking the equivalent program without templates. The only checking that occurs then is the minimal amount needed to prevent undefined behavior. In particular, this scheme is vulnerable to spurious subsumption.
This is simple fact: C++ templates to not provide as powerful a language for expression type constraints as Java's generics.
Your flippant comment about "generics... just add a little compile-time type checking and automatic casting" is half wrong -- casts are syntactic features in Java, and they don't get added by the compiler -- and half spectacularly right, but in a way that you don't seem to get. Generics are about expanding the language for type checking to make it considerably more powerful in being able to express type constraints. That's what they do, and they do it better than anything in C++.
This is why I pointed out that it's ridiculous to talk about C++ templates being "more" or "less" powerful than generics, since they serve different purposes.
 Signature Chris Smith - Lead Software Developer / Technical Trainer MindIQ Corporation
Jeffrey Schwab - 03 Jul 2006 19:35 GMT >> No, you've misunderstood. C++ templates are not just glorified macros >> in any sense. They exist primarily to support compile-time [quoted text clipped - 13 lines] > > public void doSomething(List<? extends Auditable> events); The rough equivalent would be:
void do_something(list<Auditable*> events);
> or perhaps the C++ equivalent of: > > public class MyClass<T extends Comparable<T>> { ... } This can be done in pretty much the same way as the do_something() example, but it's typically not necessary. If you just use the necessary features of T in the body of your template, the compiler will choose the right code for you automatically. If there is an alternative definition for the same template that *does* fit, it will be used; else, you'll get a compile-time error. This feature is frequently used to select among different implementations of a class or algorithm according to the capabilities of T, and is generally referred to as SFINAE: "Specialization Failure Is Not An Error."
> You see? You can't do it. These are type system features, and C++ > templates don't provide them. In fact, type-checking a program that > uses a C++ template means expanding the template and then type-checking > the equivalent program without templates. Some checks are done before the expansion (unlike macros), but others are done afterward. That part actually gets complicated.
> The only checking that occurs > then is the minimal amount needed to prevent undefined behavior. In > particular, this scheme is vulnerable to spurious subsumption. Not sure I understand the word "subsumption" in this context. :(
> This is simple fact: C++ templates to not provide as powerful a language > for expression type constraints as Java's generics. [quoted text clipped - 10 lines] > templates being "more" or "less" powerful than generics, since they > serve different purposes. I'm sorry for offending you. But you really don't seem to know what you're talking about. :(
Jeffrey Schwab - 03 Jul 2006 19:39 GMT >>> No, you've misunderstood. C++ templates are not just glorified >>> macros in any sense. They exist primarily to support compile-time [quoted text clipped - 18 lines] > > void do_something(list<Auditable*> events); Ah! I missed the case of "events" being a list of some derived type from Auditable, which was of course your point. For this, you have to use something called "template templates." I don't know whether you can specify specifically that the elements are of types derived from Auditable right in the same line; you might have to put a (compile-time) check in the body of the template. If you want, I'll give it a shot. :)
Chris Smith - 03 Jul 2006 20:28 GMT > Ah! I missed the case of "events" being a list of some derived type > from Auditable, which was of course your point. For this, you have to > use something called "template templates." I don't know whether you can > specify specifically that the elements are of types derived from > Auditable right in the same line; you might have to put a (compile-time) > check in the body of the template. If you want, I'll give it a shot. :) If you don't mind, I'd be interested in seeing it. I'm adding OT to the subject since we clearly are.
 Signature Chris Smith - Lead Software Developer / Technical Trainer MindIQ Corporation
Jeffrey Schwab - 04 Jul 2006 16:22 GMT >> Ah! I missed the case of "events" being a list of some derived type >> from Auditable, which was of course your point. For this, you have to [quoted text clipped - 5 lines] > If you don't mind, I'd be interested in seeing it. I'm adding OT to the > subject since we clearly are. Here's a generalized example, slightly modified from Bjarne Stroustrup's FAQ:
// http://www.research.att.com/~bs/bs_faq2.html#constraints
template<class T, class B> struct Derived_from { static void constraints(T* p) { B* pb = p; } Derived_from() { void(*p)(T*) = constraints; } };
template<class Container> void draw_all(Container& c) { typedef typename Container::value_type T; Derived_from<T,Shape*>(); // accept containers of only Shape*s
for_each(c.begin(),c.end(),mem_fun(&Shape::draw)); }
C++ templates are Turing-complete. They're almost a language in their own right. They are often used to do things that otherwise are only possibly with macros, but that's where the relationship ends. If you want more details, check out comp.lang.c++.moderated, and if you really want to get into it, I highly recommend the Josuttis templates book.
Chris Smith - 04 Jul 2006 16:52 GMT > // http://www.research.att.com/~bs/bs_faq2.html#constraints > [quoted text clipped - 11 lines] > for_each(c.begin(),c.end(),mem_fun(&Shape::draw)); > } Wow. That does it, all right! :) It relies on some quite clever hacks that apply the existing type system in interesting ways, rather than defining new extensions to the type system.
> C++ templates are Turing-complete. They're almost a language in their > own right. They are often used to do things that otherwise are only > possibly with macros, but that's where the relationship ends. To be clear here, I should point out that a macro can be (and often is) defined as a mechanism by which one can define extensions to a language by providing instructions by which these extensions are translated into the subset of the language without the extension mechanism. They are a very powerful concept, and are a staple of flexibility in languages like LISP and Dylan. In that sense, C++ templates are definitely a kind of macro. I am aware that C++ templates are basically Turing-complete (except that compilers may stop processing them at 17 levels of nested template instantiations), and this in no way interferes with their being macros. LISP macros, after all, are defined in LISP, which is not only Turing complete but also quite practically useful for general-purpose programming as well.
In retrospect, I regret using the term macro when talking about C++. The term unfortunately has a derogatory meaning in that context, mainly because C and C++ have had a quite diminutive macro facility for many, many years. By describing C++ templates as macros, I did not mean to imply any of those limitations.
 Signature Chris Smith - Lead Software Developer / Technical Trainer MindIQ Corporation
Jeffrey Schwab - 04 Jul 2006 18:20 GMT >> // http://www.research.att.com/~bs/bs_faq2.html#constraints >> [quoted text clipped - 15 lines] > that apply the existing type system in interesting ways, rather than > defining new extensions to the type system. These are sort-of "hacks" in the sense of using non-intuitive language features, but more explicit language features have been rejected by the C++ standards committees on the grounds that they are redundant. In practice, you rarely have to write this kind of code yourself; instead, you use a library that wraps it nicely, e.g. boost/concept_check.
>> C++ templates are Turing-complete. They're almost a language in their >> own right. They are often used to do things that otherwise are only [quoted text clipped - 7 lines] > LISP and Dylan. In that sense, C++ templates are definitely a kind of > macro. I don't know that I'd agree with that, because C++ templates don't allow the programmer to extend the language. Certainly not as much as (say) overloaded operators do. But I can see your opinion here.
> I am aware that C++ templates are basically Turing-complete > (except that compilers may stop processing them at 17 levels of nested [quoted text clipped - 8 lines] > many years. By describing C++ templates as macros, I did not mean to > imply any of those limitations. Thanks, and sorry for my earlier tone. "Macro" in C++ context usually means the preprocessor, and is kind of a dirty word. A lot of C programmers try to think of templates as macro-like when they first learn C++, and it ends up causing a lot of problems. One of the things I think Java got right is to avoid this mess by not including such a complicated preprocessor.
Joe - 04 Jul 2006 21:57 GMT > >> // http://www.research.att.com/~bs/bs_faq2.html#constraints > >> [quoted text clipped - 21 lines] > practice, you rarely have to write this kind of code yourself; instead, > you use a library that wraps it nicely, e.g. boost/concept_check. In fact this functionality for checking a type is derived from another type was added to the ISO standard c++ library with TR1 (C++ Library Technical Report 1 - although in the standard library it is called is_base_of ) along with the following related type traits functionality: add_const · add_cv · add_pointer · add_reference · add_volatile · aligned_storage · alignment_of · extent · has_nothrow_assign · has_nothrow_constructor · has_nothrow_copy · has_trivial_assign · has_trivial_constructor · has_trivial_copy · has_trivial_destructor · has_virtual_destructor · is_abstract · is_arithmetic · is_array · is_base_of · is_class · is_compound · is_const · is_convertible · is_empty · is_enum · is_floating_point · is_function · is_fundamental · is_integral · is_member_function_pointer · is_member_object_pointer · is_member_pointer · is_object · is_pod · is_pointer · is_polymorphic · is_reference · is_same · is_scalar · is_signed · is_union · is_unsigned · is_void · is_volatile · rank · remove_all_extents · remove_const · remove_cv · remove_extent · remove_pointer · remove_reference · remove_volatile
That's quite a bit of expressive power and on top of that you have the concept_check Jeff mentions above which checks that a type meets a set of requirements. For example in Java if a class implements Comparable, you can say it meets the requirements of the Comparable concept. In concept_check you can check that any type meets the requirements for the comparable concept without relying on inheritance and therefore you can also use it on fundemental types, such as integers.
AndrewMackDonna - 04 Jul 2006 21:41 GMT >>> Ah! I missed the case of "events" being a list of some derived type >>> from Auditable, which was of course your point. For this, you have [quoted text clipped - 31 lines] > want more details, check out comp.lang.c++.moderated, and if you really > want to get into it, I highly recommend the Josuttis templates book. or http://www.boost.org/more/generic_programming.html
Chris Smith - 03 Jul 2006 20:23 GMT > > public void doSomething(List<? extends Auditable> events); > > The rough equivalent would be: > > void do_something(list<Auditable*> events); ~$ cat main.cpp #include <list> using namespace std;
class Auditable { }; class Event1 : public Auditable { }; class Event2 : public Auditable { };
void do_something(list<Auditable *> events);
int main(int argc, char *argv) { list<Event1 *> e; do_something(e);
return 0; } ~$ g++ main.cpp main.cpp: In function `int main(int, char*)': main.cpp:13: error: conversion from `std::list<Event1*, std::allocator <Event1*>>' to non-scalar type `std::list<Auditable*, std::allocator <Auditable*> >' requested
> > or perhaps the C++ equivalent of: > > > > public class MyClass<T extends Comparable<T>> { ... } > > This can be done in pretty much the same way as the do_something() > example, but it's typically not necessary. Since the do_something() example didn't work, I suppose that doesn't bode well for other things done in pretty much the same way.
> If you just use the > necessary features of T in the body of your template, the compiler will > choose the right code for you automatically. Yes, absolutely; which makes templates a great mechanism for abbreviating and abstracting code, but not for more powerful type checking.
> > You see? You can't do it. These are type system features, and C++ > > templates don't provide them. In fact, type-checking a program that [quoted text clipped - 3 lines] > Some checks are done before the expansion (unlike macros), but others > are done afterward. That part actually gets complicated. You seem to have assumed a rather narrow definition of "macro". That explains some of the confusion here. I did not mean to imply such a narrow definition of a macro. Nevertheless, no checks that are interesting in terms of the expressive power of the type system are performed prior to macro expansion. Templates allow all sorts of interesting evaluation to occur within the compiler (an entire Turing complete language, in fact), but very little additional expressive power.
> > The only checking that occurs > > then is the minimal amount needed to prevent undefined behavior. In > > particular, this scheme is vulnerable to spurious subsumption. > > Not sure I understand the word "subsumption" in this context. :( It means that given:
class Dog { public: void run(); }; class Thread { public: void run(); };
and:
class Scheduler<T> { ... t.run(); ... };
it is just as valid to the language to declare Scheduler<Dog> as Scheduler<Thread>, and there's no mechanism in the language to prevent that from occurring. The example becomes more relevant when you consider operator overloading, but I think it's easier to understand with plain methods. This is just an example of the minimal thing that would be prevented by an extension to the type system to handle reasonable constraints about parameterized types. It's not the only possible benefit of such an exercise. If you'd like to point to others, I'm all ears.
> I'm sorry for offending you. But you really don't seem to know what > you're talking about. :( Feel free to correct me if I'm wrong about something. So far in this thread, I don't believe I have been wrong about anything. So far, it appears that asking whether Java generics or C++ templates are more powerful is much akin to asking whether the President of the United States is more powerful than a locomotive. Depending on whose definition of "powerful" you adopt for evaluating the question, you come up with different answers. It further appears that you responded to my message without taking the time to understand the sense in which generics in Java are powerful. Understandably, then, you reached an incorrect conclusion.
 Signature Chris Smith - Lead Software Developer / Technical Trainer MindIQ Corporation
Timo Stamm - 03 Jul 2006 20:43 GMT Chris Smith schrieb:
>> Moiristo schrieb: >>> I would [quoted text clipped - 4 lines] > I'd say that's a somewhat meaningless comparison. They have different > purposes. On a very abstract level, they both serve the same purpose of generic programmming. As Bjarne Stroustrup said: "we need to parameterize our containers with the element type and do operations on parameterized containers." That's what Java Generics do.
Timo
Chris Smith - 03 Jul 2006 23:54 GMT > On a very abstract level, they both serve the same purpose of generic > programmming. As Bjarne Stroustrup said: "we need to parameterize our > containers with the element type and do operations on parameterized > containers." That's what Java Generics do. To me, it looks as if they only serve the same purpose on a NOT very abstract level. Ultimately, generic collections of reference types in Java are possible not because of generics, but because of the existence of a universal supertype for all reference types. Generic collections or primitive data are not possible because Java doesn't provide a universal supertype for primitive data (neglecting boxing conversions), and generics don't change that.
It's important for Java programmers to understand that generics in Java are a type system feature. They do not in any way relate to what the code does! Java's generics define a somewhat intricate language for expressing syntactic constraints on situations in which certain code is appropriate. Once it is determined that the code is appropriate, the code is executed exactly as if it had not been written with generics at all. Generics allow the programmer to limit the range of uses of some piece of code, and then rely on the information added by these constraints later on.
This is a huge difference from C++ templates, the whole purpose of which is to write templates for code, which are expanded to different code under different uses. While some of the possible expansions of templates may differ from each other only in type checking, there are others that differ from each other in terms of static resolution of method calls, or even (with template specialization) completely different structures of code. At the same time, C++ templates do NOT provide any fundamentally new vocabulary for expressing type constraints. Every pure type constraint on code using C++ templates is a type constraint from the non-templated subset of the C++ language after expansion of the templates. (I'm neglecting the type constraints that are defined on non-type template parameters, as in "template<int a>", because they are outside the scope of the discussion here.) Unlike Java, in which generics augment the subtype relation with wildcard types that allow more flexible typing of expressions, C++ templates don't introduce any type relationships that wouldn't otherwise be there.
Clearly, it's possible to find similarities between these two features, but I certainly wouldn't call them abstract. Instead, the similarities seem to be that both features are used in the context of collection classes.
 Signature Chris Smith - Lead Software Developer / Technical Trainer MindIQ Corporation
Jeffrey Schwab - 02 Jul 2006 16:05 GMT > I'm pretty new to Java, but with loads of C++ experience. Today I > started working on a new ap just for fun and I was trying to decide [quoted text clipped - 5 lines] > Java makes the hard stuff easy, and the easy stuff hard. > C++ makes the easy stuff easy and the hard stuff hard. FWIW, I've said the exact same thing about Java. I wouldn't contrast it with C++ in this respect, though, but with Perl. Perl makes "simple things simple and hard things possible." I've more or less given up on using Java for everyday tasks in favor of Ruby and C++, but I do look at Java first for non-trivial applications.
C++ is good for small tasks and for large ones, but at some point you have to make a definite transition from thinking small to thinking big. It seems like there's always a hump somewhere in the middle that forces you from about 1,000 loc to 5,000.
> When will they invent a language that makes it ALL easy?! When human thought is predictable and easy to codify. In other words: Never.
> Please tell me it's going to get better as I learn more Java, 'cause I > REALLY like it, but it sure can be a pain at times. ;-)
:) Alex - 05 Jul 2006 18:49 GMT >Java makes the hard stuff easy, and __the easy stuff hard.__ It's because Java is right and force you to do all in correct way. For example, when it's possible that Exception could be thrown then you MUST say how to handle it. Even when you say _do nothing_ {} you must say it.
In C++ you just ignore (or may ignore/or may not) all troubles till they appear. Java forces you to write correct code. C## has special key _unsafe_ to be like C++. Which makes is similar and as bad as C++.
(I have assembler, C, C++ and Java experience for 10 years each). Alex.
> I'm pretty new to Java, but with loads of C++ experience. Today I > started working on a new ap just for fun and I was trying to decide [quoted text clipped - 12 lines] > > --gary
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|