views:

233

answers:

8

Before anything, let me first clarify that the below thoughts are purely my personal opinions and due to my limited knowledge. I have no intention whatsoever to say that C++ is not cool.

I've been programming C++ for like a year and I think it really has some cool features. Nevertheless, I feel a bit empty and disappointed as I didn't really learn any "mind-changing" things from C++, from the standpoint of a person who happens to have previously learned Java (as the 1st language).

According to the many posts I've read, people prefer C++ as it's faster. To a programmer like me who haven't programmed time-critical applications before, I've yet to have a chance to appreciate this.

So far, what I've learned seems to me are all about syntaxes. This is how we write a class in Java, and here's how to write it in C++. This is how to do inheritance in Java and that's how to do in C++ and so on. (I know, multiple inheritance is cool, but to me, not a mind-changing thing. I think what's cool is to be able to answer why Java didn't/couldn't support multiple inheritance, which is supposed to be more general than single inheritance).

Somehow to me, all are just syntaxes and my mind hasn't seemed to grow after coding C++, so far. I think my problem it to write C++ programs with a "Java-mind". What I really want is, as many persons suggest, to change my ways of thinking after learning a new language. I've yet to get to that with my C++.

I can also write a couple of small Python programs. However, I feel afraid to learn more about it as to me, again, it would be just learning a new syntax, a new way of doing things that are just different, without knowing the reasons.

I plan to learn C to really get to know things. I think it would be a quite "involving" language.

Let me know what you think and please give me some advice.

PS: Btw, there is one specific question in C++ I want to confirm. In C++, writing in the following way is not efficient, if I'm correct:

    private A computeAndReturnA(){...} 

Instead, write it as:

private void computeAndReturnA(A& a){...}

as in the first way, the returned values are copied (when we assign b = compute...) and introduce some inefficiencies? (In Java, I guess the 1st way is clear in meaning and okay in efficiency as it passes things by reference)

+1  A: 

Learning C is your best option here - It'll get you down to the bare bones, which forces to not use your Java mindset and as such you can have a nice, easier transition to C++.

mathepic
Personally and other may disagree. Is that learning C is a waste of time (in terms of helping you learn C++/ It is a complex language in its own right with it own way of doing things). But it will not make the transition to C++ easier.
Martin York
C and C++ are fundamentally similar. Yes, C++ is its own language, but knowing how pointers and such work is a great advantage.
mathepic
+6  A: 

You're totally wrong, in short. The fact is that C++ offers a HUGE quantity of freedom compared to Java.

For example, you can allocate classes on the stack. Java doesn't offer that. You can compute certain values at compile-time. Templates offer far more power than generics. You have the power to make something a reference, or a value. In Java all of these choices are taken away from you. Like, in C++ you can extend more than one class. You aren't forced to extend Object. Deterministic resource clean up, if you want to. I could go on and on and on and on.

If all you do is learn the syntactic variants, then it's perfectly possible to use C++ in a somewhat acceptable fashion. However, C++ offers dozens of things that you would never see in Java.

The simple truth is that Java is more like a subset of C++ with a bigger standard library, plus reflection and run-time code generation, I guess.

I prefer C++ because Java, frankly, is full of arbitrary restrictions. Do you know why there's no "friend" statement in Java? Because James Gosling thought it went against his principles. Great. That's awesome. Now I need to split my implementation up into two classes and have to pretend that it's two implementations with separate encapsulation it because he thought ten years ago that it wasn't the right thing to do. That's my personal example of why Java sucks tremendously - you program how James Gosling says you should, not how you want to or, in plenty of cases, how you actually should.

Also, I looked at your PS. That's why C++ has a proper compiler. The reality is that virtually all compilers will turn the first form into the second for you, and some other mind-bending optimizations that you don't want to know about that are done behind the scenes.

DeadMG
OK, you can do more "cool" things with C++, but does it help to solve real-world problems or does it just introduce another level of complexity?
mklhmnn
That's not the question in the OP. He wants to know what's in C++ that's not in Java, and I've told him. Besides, how can having exactly the same abilities as Java but more NOT help?
DeadMG
@mklhmnn, C++ does solve real world problems.. Also learning may be *complex* but I don think the language itself introduces another level of complexity..
liaK
java has no SIMD :(
Inverse
@DeadMG: There are a couple of features you mention that I'm really not aware of now. I really appreciate your help. I'll check them out first and then join the discussion
hungh3
@DeadMG: Thanks for your comments. I've just studied a little bit about C++ template programming and that's actually quite cool. That is made cooler by my to-day realisation that Java's Generics is not truly generic. I summarise my understanding of your points below: Template programming: +1 for providing (truly) generic programming -> faster;+1 for meta template programming -> faster;+0.25 for some added constructs that would otherwise require employment of unnecessary design patterns (w/o RTTI) -> more convenience;+0.25 for template specialisation -> more convenience;
hungh3
(cont.)Stack-based memory allocation: -> faster: +1;Friend feature: +0.25 for convenience; encapsulation can do the same thing but may be more lengthy;In short, I think Java is a language that says, implicitly, "I only allow you to play with this, but I guarantee you safety" while C++ says "I give you all my power, but use it at your own risks".
hungh3
+1  A: 

If you are trying to learn new languages to improve your programming skill, perhaps try and learn something that is quite different from the C style syntax. Perhaps one of the functional languages like Haskell, Scala or Erlang. That will show you how different programming languages can be and you'll start to realize the subtle differences between Java/C++/C as well.

Otherwise if you are aiming to solve a specific problem you can choose a language for that. Unless you have something thing is performance critical it is probably easier to stick to garbage collected languages. Unless you're planning on doing iPhone development, in which case you should switch to Objective-C

leonm
Thanks leonm for the cool advice.
hungh3
+1  A: 

On your Question: The upcoming C++0x will have move semantics, which should speed up "return by value" to comparable performance of "return by reference". These dont need a change in client code, but one may need to implement an additional constructor in the moved classes.

About your Rant: Read "Modern C++ Design: Generic Programming and Design Patterns Applied" by Andrei Alexandrescu and by surprised how much C++ and Java (and the corresponding mindset) can differ.

Markus Kull
+1  A: 

The reason why you probably don't feel like C++ offers you any kind of candy for your mind is that you come from a Java background which to all intents and purposes offers a very direct and simple translation into C++. Not the best C++ to be sure, but a possible working C++ implementation...

... The reason for the different idiom in your PS example has nothing to do with references (which Java doesn't have: Java has pointers-to-objects but not references; but C++ does have references as well as pointers) and everything to do with the fact that in Java memory allocation is relatively cheap whereas in C++ it is not (because in Java the cost of memory allocation is amortized over everything the VM needs to allocate anyway -whereas in C++ it is not- so in Java the VM ensures that memory is only allocated as needed anyway).

So in efficient C++ you see that people avoid lot's of redundant new calls in a tight loop whereas in Java people can comfortably create temporary objects all they want.

Can you elaborate more or give some pointers on why Java memory allocation is cheap while it's heap-based? My question is why C++ can't implement a heap-based memory allocation that is as efficient as Java. Thanks!
hungh3
Because in C/C++ a new or malloc call is expensive, whereas in Java the new call amounts to little more than “reserving” a bit of pre-allocated memory by the JVM. Likewise, freeing memory does not need to go through the expensive OS calls.Or in other words the cost of a malloc/new call in the underlying JVM is amortized over *all* new calls in Java code, so the average cost of a single new call in Java code is quite small compared to the C++ equivalent.
+2  A: 

The simple truth is that it takes quite some time to learn to think in a language e.g. best practices. It's a long process where you start with learning the syntax and probably in the beginning apply other language paradigms at first in order to find your way.

It's true that if you would have picked a language that is very different from Java - syntax-wise as well as paradigm-wuse you may noticed these differences earlier but don't underestimate C++ as a different paradigm.

C++ is a language that is very complicated to learn, however it's a language that can give an impression that it is easy to learn especially since the syntax is similar to several other languages however there is more to it than that. One big topic is for instance template programming, using a template is fairly straightforward however if you take a look at the boost template library you will that it can be quite complex and building such a library is not for the faint hearted.

Learning a language is just not about learning a syntax, its about learning how to think in that language.

That said, C++ is one of languages that allows you as much freedom and control as you want, sometimes too much freedom.

Anders K.
+1 I like yours, may be cos of *Learning a language is just not about learning a syntax, its about learning how to think in that language*.. :)
liaK
+1 for "sometimes too much freedom". I think just as in life, (more) freedom usually comes with a (higher) price, such as less security. And coding "normal" programs may not *actually* needs much freedom...but great tools and programs built by true hackers do.
hungh3
+1  A: 

Definitely have a look at www.boost.org, that will be a mindset-changing experience.

As for the question in Post Scriptum: if the first form will involve copy or not: it depends, and depends on many factors.

In current C++:

The first is that if the compiler supports RVO and especially when it also supports NRVO, chances are high copy will not take place. Then it depends on how the function is written:

A computeAndReturnA()
{
   return A( x, y );  // no copy almost for sure
}

A computeAndReturnA()
{
   A a;
   a.f();
   a.g();
   return a;  // no copy if compiler implements NRVO
}

A computeAndReturnA()
{
   A a;
   while ( condition1 ) {
      a.f();
      if ( condition2 )
         return A();  // copy will take place
   }
   a.g();
   return a;  // copy will take place
}

Then it depends on how you call the function:

A a1 = computeAndReturnA();   // no copy if function body written appropriately,
                              // return value will be constructed directly in a1
A a2;
a2.foo();
a2 = computeAndReturnA();     // copy regardless of function body,
                              // return value can't directly be constructed in a2
                              // as a2 is already constructed

In upcoming C++ (March 2011?):

The same reasoning as for current C++ applies. However, if that reasoning suggests that copy would be made, and if the class (A here) has move constructor and move assignment operator, then 'move' and not 'copy' will take place. In the ideal cases the move will be elided as well as you get direct construction, but if not you'll get move in the worst case, of course provided that the class being returned is move-aware.

I think you'll find this article interesting and informative: http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/

usta
Thanks for your explanations. I really learn a lot from yours and the link. Btw, do you know how can I check if a compiler performs RVO or NRVO or none?
hungh3
Most *modern* compilers do both, if not all of them. GCC does it starting from 3.1 (around 2002). But to be sure I think the only way to check is to look at the disassembly of the generated code and see if the function called takes a hidden pointer (address) to construct the return value into. Or the compiler might indicate if it supports RVO in its documentation. For example:http://msdn.microsoft.com/en-us/library/ms364057(VS.80).aspx
usta
Usta, thanks for your advice.
hungh3
+1  A: 

C++ is much more general than Java, in the sense that it is, as pointed in other answers, a multi-paradigm language, where as Java only stresses object-oriented programming (and a single way to do OOP, at that).

You can certainly do many things in C++ that you couldn't dream of in Java. However, for someone who has a Java background, I'd argue that C++ is a very bad learning vehicle, as it is way too easy to simply code in Java with a few "delete" statements here and there.

If you want some mind-changing experience, you should learn a language that actively stresses another paradigm, instead of a language that lets you choose whatever paradigm you want.

I would suggest one of Haskell (functional programming), Erlang (an uncommon approach to concurrency), Factor (stack-based programming), Prolog (logic programming), Common Lisp (CLOS & macros), Javascript (prototype-based OOP, i.e. without classes).

These would, in my opinion, be mind-changing learning experiences. I would argue that, even though they do support many things that Java doesn't, Python and Ruby are still pretty close to the Java model; indeed, with a Java background, it would be quite easy to see them as just another skin on the same model, with a slightly different syntax and no type declarations.

My point is, if you want to blow your mind, you have to learn a new paradigm. And while it is certainly possible to learn new paradigms on a sufficiently powerful language such as C++, it will be much easier to learn the new paradigm through learning a language that forces you to use that paradigm.

For a brief overview of some mind-changing ideas, you could watch these video lectures.

Gary Verhaegen
Thanks for your answer. Your answer makes a lot of sense. And thanks for the link, also. Btw, It seems to me like all these valuable resources all scattered around the Web, I don't know if you know anyone has tried to assemble and categorize these resources (sth like Google Directory)?
hungh3