Thinking in C++? - c++

The programming language I use has been Java. I've been transitioning to C++ which has been somewhat rocky. The "rocky-ness" isn't in the learning but more along the lines of "Thinking in C++".
I've seen many people say that you should learn C first (I technically know it already), and then I see people say no skip C and go straight to C++. Once again this isn't a "learning" problem; it's a "thinking in" problem; I know the syntax to C++, I know OOD in C++, etc.
For example this code in SDL I can explain it as if I know it but I cant really "take advantage" of pointers:
SDL_Surface* hello = NULL;
Should I be programming in C to get "used" to this? What should I be doing to get used to pointers if I've never used them coming from a language such as Java?

It's true that pointers are a big deal, and C and C++ share that concept.
But C++ is not just C with objects.
There are two free books that you can download from Planet PDF by Bruce Eckel called Thinking in C++ (volumes I and II) that will really help you get the sense of C++.
A lot of C++ also is the toolkit, whether it be the standard library (std) or MFC or the classes from the anti-grain geometry library or whatever. That too makes a difference.
If you need C++, go for C++. Learning C first is like learning Spanish so you can learn Portuguese, instead of just aiming for Portuguese.

If you understand the syntax, then the only way to become "fluent" in a language is to use it.
Using C is a good way to keep things simple and get close to the "metal", but it isn't the same as C++, so ultimately I would advise using C++ if you wish tolearn C++. (i.e Don't learn Latin if you want to be fluent in Italian, even though Latin will give you many insights, the two languages are different beasts, and the thought processes involved are correspondingly different)
Pointers are very easy, once you "get" them. A very good idea when using pointers is to use the "p" prefix notation. For each pointer (level of indirection) add a "p" to the front of your variable name to remind you that it is a pointer:
Vehicle vehicle = an actual vehicle
Vehicle *pVehicle = a pointer to a Vehicle
Vehicle **ppVehicle = a pointer to a pointer to a Vehicle
To access the vehicle you have to dereference once for each pointer, i.e:
vehicle.SetName("Ford Focus"); // Directly access an object instance
(*pVechicle).SetName("Ford Focus"); // Dereference once
(**ppVehicle).SetName("Ford Focus") // Dereference twice
There are three ways to dereference (just different syntaxes that generate identical code):
(*pVehicle).DoSomething()
pVehicle->DoSomething()
pVehicle[0].DoSomething()
When you use arithmetic on pointers they operate in Vehicle units, not in bytes, i.e
pVehicle++; // Move to the next vehicle record, not just the next byte
And finally, for each
pVehicle = new Vehicle
you need to balance your code with:
delete pVehicle;
pVehicle = NULL;
(edit) Oh, and almost forgot the most important one: ALWAYS check that your pointer is valid before you try to use it!
if (pVehicle != NULL)
...use pVehicle
I find the "p" notation invaluable as you never forget that something is a pointer, and the number of p's tells you how many dereferences are needed. Once I adopted it, I stopped writing NULL dereference/access violation bugs.
That's all you need to know about pointers. Now you just have to use them a lot to gain fluency.

Should I be programming in C to get
"used" to this?
No, you shouldn't. C used to be a good introduction to C++ when C++ was mostly thought of as "C but with classes". C++ has evolved so much from that mindset that writing C code in C++ makes for very very bad C++ code.
What should I be doing to get used to
pointers if I've never used them
coming from a language such as Java?
Knowing how to use pointers in C++ implies several key areas (and you should probably learn them one after the other):
pointer arithmetic (adding and substracting pointers and integers, usage of zero pointer, pointers and arrays, operations with pointers); this is the part C++ shares with C.
pointers to functions (this part is also shared with C).
pointer casting (static_cast, dynamic_cast, ...). This part is C++ specific. You could also define your own cast type and experiment with that a bit (and have a look at boost::lexical_cast as an example).
pointers to member objects and member functions.
RAII for pointers and various smart pointer implementations: circularly-linked pointers, reference-counted pointers (boost::shared_ptr), unique pointers (std::auto_ptr), scoped pointers.
wrapping function pointers in functor classes (see std::tr1::function or boost::function).
object references and how they are like and unlike pointers; Where to use references and where to use pointers.
the similarities between pointers and iterators.
using operator* and operator-> to simulate pointer-like behavior for an object (and when not to abuse this).
pointers and constness / mutability: what is the difference between a pointer, a const pointer, a pointer to a const value and a const pointer to a const value (and when to use each), and similar using mutable pointers.
Current best practices in C++ advice against using pointers in your code unless they are managed automatically by your code (through RAII for example).

I don't think that learning C will help with your "thinking" in c++". Generally, you just need to get used to certain C++ concepts and why they are useful.
Key ones are smart pointers (more generally RAII) and templates which are huge.
Also keep in mind that c++ is a multi-paradigm language, not strictly OOP. Often the best solution isn't very object oriented at all (the STL is a great example of templates being better design than an object based one).

You know, there's a very well-regarded book that's actually entitled "Thinking in C++" :) Even better, it's free! It should help you grok things like pointers on a deeper level -- it's explicitly geared towards that.

A programming language is just a tool. The bottom line is, the more you know the better. C is a very good language to learn IMO, for the very same reasons one of the co-founders of stack overflow (Joel Spolsky) mentions in this article: http://www.joelonsoftware.com/articles/CollegeAdvice.html. I read this article before I graduated and made it a point to take his advice on learning C before I graduated.
At the end of the day, software written in any language is run on (or by) a computer chip. It's very important to understand (if you want to be a 'good' programmer anyway) what the cost is (in cpu time and programmer time) of the mechanisms you are using in whatever language you are using. High-level languages are great for programmers in some cases because they allow you to implement powerful end-user features more quickly than lower level languages such as C. However, lower-level languages in general provide better performance. The only thing you as a programmer need to consider is 'what is the right tool for the job?' You don't use a hammer to drive in a screw, blah blah insert other cooker cutter analogy here, etc.
One thing that high-level languages tend to hide from the programmer is pointers. Pointers is a very important concept to be familiar with whether you program in a language that hides them from you or not. C is a great language to learn pointers (or C++ for that matter). Recursion is another big one, but I don't think any language can really hide this concept... it's a generic problem solving concept whereas pointers is more of a mechanical detail.
Lastly, my degree did not actually require me to take a compilers course. I could have ducked it, but since it is one of the most notoriously difficult classes, I felt I would be less of a man if I didn't take it. I did horrible grade wise, but I learned so many important things in that class it was well worth the proverbial rock I tied to my GPA by taking it. If you learn how a programming language is actually implemented then you have a huge advantage vs just knowing how to work with 'language X.' Any programming language takes time to learn, even if you do have all the fundamentals in the world. Random jerks everywhere will try to tell you how easy it is to learn 'language X,' but these people are usually just insecure and want to make themselves feel good by acting like they were born with an ability to program in 'language X' when really they have just put in the hours to learn it. Nobody is born knowing this stuff, just give yourself time to learn but be smart about it. Develop a systematic method of learning a new language (my strategy always starts with writing 'hello world' in the language) and you will do fine. END RANT.

I say focus on the topics you're having problems getting your head around. Pointers are for the most part the same in C and C++, so pick whatever resource will help you the most.
My girlfriend had trouble in pointers when starting out in C++, and she recommends a book called Understanding Pointers in C.
What's to get about pointers that's specific to "thinking in C++"?
Pointers can be set to NULL (i.e. 0). This can be fabulously useful to model situations where you might have a value.
Pointers can be repointed to new objects – as opposed to, say, references, which only get initialized once and cannot be repointed after initialization.
Pointers can be implicitly upcast (from derived classes to base classes).
Pointers can be explicitly downcast from base classes to derived classes. You can do this with static_cast if you happen to know what the derived class really is! People generally do this with dynamic_cast for the extra runtime sanity check.
Pointers can be cast to and from void* if you want to pass a pointer to someone but you don't want them knowing the kind of object that you're pointing to. In other words, pointers can be made opaque.
Pointers and arrays are nearly equivalent.
Here are some things related to pointers that are unique to C++ vs. C:
C++ has the concept of references, which can be used in many of the situations pointers are used in, but are much more difficult to screw up (in terms of dereferencing an invalid address) than pointers.
C++ has the concept of pointers to member functions that are a bit different from pointers to functions, which C also has.
In C++, you can define your own objects which behave like pointers – i.e. that you can dereference using the * unary operator. C++ libraries use this feature to implement smart pointers, which are a whole category of objects that behave like pointers but which also have some layer of access or ownership management built into them.

In my opinion, C++ as a language is so complex that understanding of it is still evolving. I'm still discovering new programming techniques. And C is no longer a good introduction to C++. In fact, becoming too steeped in C will teach you bad C++ habits and will tend to blind you to some of the really useful things in C++. For example, in C++, I consider pointers to be more important than in Java, but not nearly so much as in C.
There is no magic book you can read or formula you can follow to learn to think in C++. You have to practice with the concepts. Write your own programs that use them, even if they are just toys.
Here is my personal list of important C++ ideas that you should practice with and grow used to using:
Using swap (and in C++0x the move constructor and assignment operator) to write code with a strong exception guarantee.
Template metaprogramming (templates are basically a functional language inside of C++ who's output is a C++ program).
The RAII idiom (RAII stands for resource acquisition is initialization) - this is something in C++ that is fundamentally different from Java, and very important to understand.
And, related to RAII, the concept that objects of non-primitive types are routinely created without using new. You create objects directly on the stack or refer to them by inclusion rather than by reference. This is a huge, but subtle difference from Java.
Iterators - what the non-Javaesque use of pointers has turned into for the most part
And really, pointers that aren't used as iterators are just the same as variables of non-primitive types (i.e. stuff derived from Object) in Java, except for the lack of garbage collection.

This question has nothing to do with thinking in C++. You just need to learn more C++. It's good that you already know Java, because just about everything important in Java is directly present in (and indeed borrowed from or influenced by) C++, so you just need to learn more C++ to learn how to "map" those Java design ideas into C++ implementations.
Do not learn C to learn C++. That's a stupid myth. They are two different languages. Learn C++ to learn C++.

If you are really thinking of mastering pointers concept , I will suggest this book:
Understanding Pointers in C by Yeshwant Kanitkar .
Its very lucid and organized book that will give you the deep insight of pointers starting from scratch to the applications of pointers.

If you are already working in a C++ project on a daily basis, chances are that you are already getting used to using pointers. It just takes longer time for the knowledge and recurring patterns to sink in. (If I remember correct a famous C++ guru says it takes 6 months to a year to become productive.)
A good debugger, especially one which shows the original source code and the compiled assembly code at execution time, will help you understand better.
To echo Evan Thinking in C++?, C++ is a multi-paradigm language. To think in C++ is mainly about thinking in paradigms. For example, libtiff is entirely based on function pointers and COM is entirely about OOP using nothing but pointers, vtables and reference counting. MFC wraps a lot of things into macros and tables.
At the beginning of a project, you have a chance to choose the right paradigm. Sometimes it is limited by the project requirements especially if it needs to interface with an external environment. Once the project gets going, it will be difficult to switch. Often the choice was made for a good reason.
The only way to learn about a paradigm is to work in a project that uses it.

Related

What are the best strategies and examples for teaching C++ memory management to early college students?

So I'm teaching a 2nd semester freshman level C++ course at a university in an upcoming semester. The students have used arrays (though only statically allocated) and have some notion of references and pointers (but probably not much). In general, they have not done a whole lot of dealing with dynamic memory allocation and management. I'm trying to sort of harness the global intelligence of the Stack Overflow community to see, in your collective experience, what have been the most effective ways to teach things like pointers and memory management to young computer science students?
There are a lot of existing interesting StackOverflow posts on related topics:
When teaching C, is it better to teach arrays before or after pointers?
What are the barriers to understanding pointers and what can be done to overcome them?
What is the real difference between Pointers and References?
should we teach pointers in a "fundamentals of programming" course?
What are the important notions in C that you did not learn from your teachers
I certainly have my own set of opinions on how and what I teach, but I'm really interested in how my methodology differs from yours. Some sub-questions to consider (you're certainly not limited to these):
What order would you teach things in and how would you relate the topics? "Ordinary" stack variables, followed by references, followed by pointers? Where do arrays fit in? When do you introduce the "new" keyword? etc.
What visual aids have you seen used that best express these concepts? e.g. Drawing boxes for memory locations with values inside and variables/pointers as names with arrows pointing to the boxes? Are there any particular websites or textbooks you've read that just have outstanding descriptions?
Are there particular code examples (e.g. a "swap" function) that tend to get the information across better than others?
Teach on!
Edit
In an attempt to differentiate this from some of the links I've posted:
Most of the previous SO links I've posted focus themselves very directly on pointers. Though pointers are an integral part of understanding memory behavior, I'm interested in the more overarching themes of how students understand how memory works in general. How do we best illustrate the differences between normal, pointer, and reference declaration? How do we emphasize the differences between global, stack, and heap variables? I think even getting into pushing return addresses onto the call stack is fair game too. What do you think the most important aspects of memory management are, how do you tie them all together, and how do you get this across in a coherent fashion?
I've seen the blinky video before. Its a bit odd but it does illustrate the point.
The best analogy I have found for teaching the concept of pointers is that of the URL. The web page is the memory and the url is the pointer. Every student will be familiar with them and it is a "concrete" example of the indirection.
As for ordering, I would think static allocation followed by pointers and only then references. References, while simpler, are in many ways a special case of pointers and introducing them before requires teaching about most of the pointer concepts.
Since I've always been a logical person I mostly would like to hear why you need dynamic allocation, not how it works and how the syntax is in a particular language. Start with static allocation, move on to cases when you hit the limitations of it, introduce dynamic allocations. Try to explain the different runtime scopes (compile time, runtime and the border cases). Explain which allocation techniques to use when. For heap allocation you could use shared memory situations and show that it is necessary to have a referencing mechanism, and introduce pointers through that. Show that you cannot determine the lifetime of the memory area easily with shared owner semantics and show different solutions (reference counting, manual deallocation etc) and describe why you need a tradeoff and not just one solution. Use other examples than only memory allocation (e.g RAII) to show that the techniques you show are not limited to memory but to any type of resources.
I think that the key is to build the knowledge from the ground up, and not treat people like idiots (Blinky), but to keep in mind that many people have limited experience in the field, and need concrete examples to grasp why all the features are in place. There are many factors in play, and clearly defining the constraints so the students understand the problem formulation is probably the most important aspect of teaching this type of things.
An example is worth a thousand words, and giving students concrete examples where the things they know so far doesn't cut it enables them to reason about the problem and eventually take the next step.
Build a microprocessor. Understanding that memory is laid out linearly (there is no such thing as a 2 dimensional array on most computer architectures and [][] is syntatic sugar), and addressed by a MUX is something I never understood until then. From there everything else builds on this, including how addresses get into the registers, processed by the ALU and put back into memory and/or pushed on the stack.
If someone would hire me to teach memory management, bless their naive hearts, I would start with the heap/stack difference.
Count variable? I'd stack that.
Reading an unknown amount of values? Don't know about you, but I'll throw them on the heap.
Things like that.
If you are teaching just about pointers, it's another game.
I think my teacher used this analogy:
A pointer is an address(duh), the value is the house.
I guess anybody can understand at least that much.
I'm always trying to simplify stuff(too much sometimes). Maybe this helps.
I'd suggest that you start by discussing object life cycles. How objects are created and how the programmer controls when they're deleted. This will instill an understanding of the the necessary abstractions before you get into the basics of pointers. Life cycles relate to and motivate all of the concepts you've mentioned above: stack based allocation, C++ references, and pointers.
If you think think your students are ready for it, you might discuss smart pointers, as well. If you can teach them to eschew raw pointers as much as possible, you will save them and their future coworkers a good deal of grief.

Learning C++ and overcautiousness

How should I learn C++? I hear that the language gives enough rope to shoot myself in the head, so should I treat every C++ line I write as a potential minefiled?
How should I learn C++?
Refer to:
Books to refer for learning OOP through C++
https://stackoverflow.com/questions/631793/good-book-to-learn-c-from
The Definitive C++ Book Guide and List
https://stackoverflow.com/questions/1122921/suggested-c-books
https://stackoverflow.com/questions/1686906/what-is-a-very-practical-c-book
https://stackoverflow.com/questions/681551/a-c-book-that-covers-non-syntax-related-problems
I hear that the language gives enough
rope to shoout myself in the head, so
should I treat every C++ line I write
as a potential minefiled?
A C++ statement can do either what you want it to do, or something else. This depends on your understanding of what that C++ statement means. But this is not specific to this language.
By learning the language, and using techniques for building correct software (like Object Oriented design, especially Design by Contract, and testing techniques), you will be able to guarantee that your program behaves as you intended it to.
I love your metaphor! What Stroustrup actually said was:
http://en.wikiquote.org/wiki/Bjarne_Stroustrup
C makes it easy to shoot yourself in
the foot; C++ makes it harder, but
when you do it blows your whole leg
off.
This was many years ago. I started learning C++ in ca. 1991 and it really was a minefield. There were no common libraries, no debuggers and the AT&T approach used a C code generator. There are now many good IDEs which support C++.
Personally I moved to Java because I find it a cleaner language but C++ is fine as long as you don't try to be tricky. Avoid native C constructs where there are existing class libraries (Stroustrup initially did not provide a String class as he though it a useful "rite of passage" to have to write one!) Now you can use a proven one.
I'm assuming you have no choice in the language. How you go about it depends on where you are coming from. C++ is not the easiest of the object-oriented languages to start on and Stroustrup's book is not necessarily the best intro.
UPDATE the OP is worried about blowing themselves up when learning the language. Generally it's a good idea to start with a subset of what one will do later. I assumed the OP is worried about:
Things which you have to know and use whatever level you program at (such as destructors)
Things which add additional complexity to the learning process and can be shelved until later (such as multiple inheritance)
what follows are some places where I blew myself up... They are not subjective, they happened!
There are some up-front gotchas that don't exist in Java or C#.
destructors. You have to manage your own memory. Failing to write destructors will blow your fingers and toes off.
equality. You will have to write an equals method (in simple Java you may get away without it)
copy constructor. Ditto. a = b will invoke this. Bites you in the bottom.
And I'd suggest avoiding multiple inheritance unless you really need it. Then avoid it anyway.
And avoid operator overloading. It looks cute to write:
vector1 = vector2 + vector3;
but
vector1 = vector2.plus(vector3);
is just as clear, only a few more characters, and you can search for it.
Well, it's not a minefield.
Really, the most problems are related to anything related to pointers, so you'll have to understand them (which it's not easy at first) and be careful when using them.
I think it's more a question of experience, having all the basics clear and trying to get a clear design since the beggining.
More than a minefield, I think it's like going to the most dangeours neighbourhood in your town. Yes, it's dangerous, but only for the ones without the attitude. :-D
I would say that that C++ is a challenging environment, if not a minefield. The fundamental issue is that problem symptoms and problem causes are not always easy to tie up. As Khelben has said one major reason for that is that we have pointers to deal with and hence we can do quite a lot of damage when pointers are not pointing where we think they are.
So you need to pay special attention when dealing with arrays and pointers, out-by-one errors can result in memory corruption and these then result in interesting problem manifestations.
Every formal language is a minefield. There're less mines in managed environments. For instance, in C# if you overblow an array you won't cause someone else's remote function to do strange things. You won't have code run differently in tests and prod because someone forgot to initialize a variable in constructor.
However, these are the easy ones. You learn to avoid them, and then you stay with the real mines, which are there in every language.
More specifically, these are some of the most important points when moving to C++:
always initialize variables. even theoretical possibility of having your program logic depend on what was in the memory beforehand is a nightmare.
dependencies: avoid data members of other compound types (classes) without pimpl idiom. This will make your users exposed to the inner workings of the types you use, and increase compilation time dramatically. Dependencies are your enemy.
in C++, you can optimize for performance in ridiculously huge number of ways. don't. Unless you are in the innermost loop of a heavy math software, and even then don't.
avoid DLLs on windows. They don't work with singletons, causing problems to popular libraries.
use boost, shared pointers whenever you can. avoid reinventing the wheel and regular pointers.
use std::string, smart containers instead of arrays. These are dangerous. It will be faster than managed containers anyway.
use RAII. This one is priceless.
prefer data members to inheritance, or you will expose the base type definition to your type's users.
learn to avoid nested includes with forward declarations.
How should I learn C++?
depends. where are you coming from? anyway, I'd suggest:
use an up-to-date compiler such as gcc-4.4 or 4.5
C++0x is worth it for the type inference alone (local variables don't need explicit type designations)
write small, standalone, short-lived utilities (try porting such tools written in other languages)
STL has complex parts, but the basic things are easy, don't shy away from it. FMPOV it embodies the spirit of C++
use state-of-the-art C++ libraries: stuff like Boost.Foreach, Boost.Tuple, Boost.Regex or Boost.Optional turn C++ into serious competition in the scripting department
when you're comfortable:
learn to generalize your code with templates
learn to use RAII
then:
add C libraries to the mix. this might be the first time you'll need to tinker with pointers and casts!
add OOP if you feel like it
should I treat every C++ line I write as a potential minefiled?
be cautious, but don't worry too much. it's true that you can't know what a + b means without knowing the whole program containing such an expression because of operator overloads and argument-dependent lookup, and I've seen many people whine about it. a killing counter-argument is that you cannot really know what a->plus(b) does in Java or a scripting language in the face of inheritance: all methods are virtual, yoyo effect in extremis! (this does kill me in large codebases with rampant inheritance written in languages w/o ADL or operator overloading!)
anecdotes from my experience learning basics of C and C++:
C: unless you do something really, really, really stupid, the program will compile just fine, and SIGSEGV or SIGBUS as soon as you run it
C++: unless you do something really, really, really "clever", the program will either fail to compile, or compile and do what you mean (a mantra Perl "inherited" from Interlisp as I've been told).
a ranty post scriptum:
C++ can be used as a much higher-level language than C: whereas you can't do almost anything beyond simple arithmetic without pointers in C, it's possible to write complete programs in C++ without a pointer in sight, save for char **argv.
there's a whole class of programs that can be implemented in C++ using it as a "scripting" language with unparalleled runtime speed and simple runtime environment (the "dll hell" is nothing compared to the volatility of real scripting languages).
however, the "scripting language" cloak is a leaky abstraction: it's built from native C++ mechanisms such as ADL, operator overloading and templates, and that has its price. get ready for abysmal compile times and unintelligible error messages. OTOH, at least the error messages can be greatly improved with tools like STLfilt, and I think it's well worth it overall.
one thing where C++ really shines in contrast to environments such as Java (perhaps C# too? don't know that one that well) is destructors (vs finalizers and GC). it's one of the pillars of the "scriptiness" of the language. whereas GC adds a whole level of semantic complexity (things don't cease to exist as soon as they're inaccessible from the program) and syntactic verbiage and duplication (finally), destructors are the workhorse of natural semantics and obviate code duplication that's unavoidable with finally.
BTW, "enough rope to shoot myself in the head" almost killed me. I think I'll borrow it. ;)
C++ has some pitfalls certainly, but writting safe code is certainly possible.
Some things to think about. There are far from the only things for writting safe C++ code but they seem like a good start.
Use std::string and std::vector to store strings and collections rather than C style strings and native arrays. They are much easier to get right.
When you allocate an object using new always think about who owns the pointer to this memory and is responsible for deleting it. If you can't think of a single owner for the data that manages it's lifetime, then either rethink your design or think about using a "smart pointer" to manage the lifetime.
Prefer indexing into arrays rather than using pointer arithmetic where possible. Whenever you index into an array every time ask your self "How do I know that this index can only index a valid index in the array".
If a class has a pointer to some data then write methods to act on that data. Don't write methods that return that pointer or at some point you'll end up using the pointer after the data has been deleted. (Not always possible but something to aim for)
If you write simple code that uses strings and vectors and as much as possible encapsule pointers as members of classes that both manage the lifetime of the data and provide the methods that act on that data then that's a good strarting point.
As others have said, read effective c++ and other books.
In C++, foot shoots YOU.
The question is do you need it for anything? If you want to make game code, 3d tools, or something similar you pretty much have to have it. If not, you don't. The errors people are afraid of are seldom big killers but there are plenty of other things that will come up if you make a large enough project.
You may find this spoof interview with Bjarne Stroustrup to be enlightening:
http://www-users.cs.york.ac.uk/susan/joke/cpp.htm
The syntax of C++ is easy, just like Java or C# with pointers. So learning C++ is fast.
The hard thing is that when it comes to a project, C++ is harder to use and more error prone compared to Java or C#. It is just too flexible and the programmer is responsible for too many things.
In a 100 lines of code, you don't need to worry about memory and null pointers at all as you can find them quickly. But when it comes to 10000 lines of code, memory management could be hard. The exception mechanism in C++ is also weak. Thirdly, you need to worry the null pointer problem in C++ in a big project.
I look at the dilemma from a different perspective. The more discipline you have in development the faster you can develop quality robust code. Assembly requires more discipline than C. C requires more discipline than C++.
Don't worry about hanging yourself, blowing your foot or leg off. Just work on improving your quality develop process. For example, a code review will help regardless of the language. Unit testing and test frameworks will also save some bloodshed. Everything boils down to project deadlines and money.

What if any, programming fundamentals are better learned in C as opposed to C++?

As a person who wanted to increase his fundamental programming skills, I chose to learn C++ instead of C. Which leads me to ask: Is there any fundamental skills that I leave in C that might not be obtained by learning C++?
Related question: Should I learn C before learning C++?
If all you've ever used is object-oriented programming languages like C++ then it would be worthwhile to practice a little C. I find that many OO programmers tend to use objects like a crutch and don't know what to do once you take them away. C will give you the clarity to understand why OO programming emerged in the first place and help you to understand when its useful versus when its just overkill.
In the same vein, you'll learn what it's like to not rely on libraries to do things for you. By noting what features C++ developers turned into libraries, you get a better sense of how to abstract your own code when the time comes. It would be bad to just feel like you need to abstract everything in every situation.
That said, you don't have to learn C. If you know C++ you can drag yourself through most projects. However, by looking at the lower-level languages, you will improve your programming style, even in the higher-level ones.
I don't think there are any skills that you can learn in C but not C++, but I would definitely suggest learning C first still. Nobody can fit C++ in their head; it may be the most complex non-esoteric language ever created. C, on the other hand, is quite simple. It is relatively easy to fit C in your head. C will definitely help you get used to things like pointers and manual memory management much quicker than C++. C++ will help you understand OO.
Also, when I say learn C, it's okay to use a C++ compiler and possibly use things like iostreams if you want, just try to restrict yourself to mostly C features at first. If you go all out and learn all the weird C++ features like templates, RAII, exceptions, references, etc., you will be thoroughly confused.
Compare the following code examples (apologies, my C++ is a little rusty).
C++:
int x;
std::cin >> x;
C:
int x;
scanf("%d", &x);
So, what do you see above? In C++, a value is plugged into a variable. That's cool, but what does it teach us? In C, we notice a few things. The x has a funny & in front of it, which means it's address is being passed. That must mean that the scanf function actually needs to know where in memory x is. Not only that, but it needs a format string, so it must not really hvae any idea of what address you're giving it and what format it's getting information in?
C lets you discover all these wonderful things about how the Computer and the Operating System actually work, if you will put effort towards it. I think that's pretty cool.
There is certainly one thing: memory management. Take following code for example:
struct foo {
int bar;
char **box;
};
struct foo * fooTab = (struct foo *) malloc( sizeof(foo) * 100 );
for(int i = 0; i<100; i++) {
fooTab[i].bar = i;
fooTab[i].box = (char **) malloc( sizeof(char *) * 10 );
for(int j = 0; j<10; j++) {
fooTab[i].box[j] = (char *) malloc( sizeof(char) * 10 );
memset(fooTab[i].box[j], 'x', 10);
}
}
Using C++ you simply do not deal with memory allocation in such way. As a result, such skills may be left untrained. This will certainly result in e.g. lower debugging skills. Another drawback may be: lower optimizing skills.
C++ code would look like:
struct foo {
int bar;
static int idx;
vector< vector<char> > box;
foo() : bar(idx), box(10) {
idx++;
for ( auto it = box.begin(); it != box.end(); it++) {
it->resize(10,'x');
}
}
};
int foo::idx = 0;
foo fooTab[100];
As you can see there is simply no way to learn raw memory management with C++-style code.
EDIT: by "C++-style code" I mean: RAII constructors/destructors, STL containers. Anyway I had probably exaggerated, it would be better to say: It is far more difficult to learn raw memory management with C++-style code.
I find it's better to learn memory management in C before attempting to dive into C++.
In C, you just have malloc() and free(). You can typecast things around as pointers. It's pretty straightfoward: multiply the sizeof() by the # items needed, typecast appropriately, and use pointer arithmetic to jump all over the place.
In C++, you have your various reinterpret_cast<> (vs. dynamic_cast, etc) kind of things, which are important, but only make sense when you're realizing that the various castings are meant to trap pitfalls in multiple inheritance and other such lovely C++-isms. It's kind of a pain to understand (learn) why you need to put the word "virtual" on a destructor on objects that do memory management, etc.
That reason alone is why you should learn C. I also think it's easier to (at first) understand printf() vs. the potentially overloaded "<<" operator, etc, but to me the main reason is memory management.
I wouldn't say you missed anything fundamental. Check out Compatibility of C and C++ for a few non-fundamental examples, though.
Several additions of C99 are not supported in C++ or conflict with C++ features, such as variadic macros, compound literals, variable-length arrays, and native complex-number types. The long long int datatype and restrict qualifier defined in C99 are not included in the current C++ standard, but some compilers such as the GNU Compiler Collection[3] provide them as an extension. The long long datatype along with variadic templates, with which some functionality of variadic macros can be achieved, will be in the next C++ standard, C++0x. On the other hand, C99 has reduced some other incompatibilities by incorporating C++ features such as // comments and mixed declarations and code.
The simplicity of C focuses the mind wonderfully.
With fewer things to learn in C, there is a reasonable chance that the student will learn those things better. If one starts with C++ there is the danger of coming out the other end knowing nothing about everything.
It really depends on which subset of C++ you learned. For example, you could get by in C++ using only the iostreams libraries; that would leave you without experience in the C stdio library. I'm not sure I would call stdio a fundamental skill, but it's certainly an area of experience one should be familiar with.
Or perhaps manually dealing with C-style null-terminated strings and the str*() set of functions might be considered a fundamental skill. Practice avoiding buffer overflows in the face of dangerous API functions is definitely worth something.
This is just a shot in the dark, but perhaps you use function pointers more in C than in C++, and perhaps utilizing function pointers as a skill might be boosted by starting to learn C. Of course all of these goodies are in C++ as well, but once you get your hands on classes it might be easy to just keep focusing on them and miss out on other basic stuff.
You could for example construct your own inheritance and polymorphism "system" in pure C, by using simple structs and function pointers. This needs a more inventive thinking and I think builds up a greater understanding of what is happening "in the box".
If you start with C++ there is a chance that you miss out on these little details that are there in C++ but you never see them, since the compiler does it for you.
Just a few thoughts.
Depends on how you approach C++. I would normally recommend starting at a high level, with STL containers and smart pointers, and that won't make you learn the low-level details. If you want to learn those, you probably should just jump into C.
Playing devil's advocate, because I think C is a good starting point...
Personally, I started learning with C, algorithms, data structures, memory allocation, file manipulation, graphics routines... I would call these the elementary particles of programming.
I next learned C++. To over-simplify, C++ adds the layer of object-oriented programming - you have the same objectives as you do regardless of language, but the approach and constructs you build to achieve them are different: classes, overloading, polymorphism, encapsulation, etc...
It wasn't any educated decision on my part, this is simply how my programming course was structured, and it worked out to be a good curriculum.
Another simplification... C is basically a subset of C++. You can "do C" with C++, by avoiding to use the language features of C++. From the perspective of language features. Libraries are different matter. I don't think you will get past more than just programming 101 without beginning to use and build libraries, and there is enough out there to keep you busy for a lifetime.
If your goal is to learn C++ ultimately, then beginning with "C" could be a logical start, the language is "smaller" - but there is so much in "C" that you would probably want to narrow your focus. You are tackling a bigger beast, but if you get guidance, I see no compelling reason not to, despite the path I took.
Most C code can be compiled as C++ code with a few minimal changes. For examples of a very few things that can't be changed see Why artificially limit your code to C?. I don't think any of these could be classed as fundamental though.
C is essentially a subset of C++. There are differences as highligted by some of the other answers, but essentially most C compiles as C++ with only a little modification.
The benefits of learning C is that it's a much more compact language and learning it is therefore quicker. C also requires you to work on a relatively low abstraction level which is good for understanding how the computer actually works. I personally grew up with assembly and moved to C from there, which I now see as a definitive advantage in understanding how compilers actually map high abstraction level contstructs to actual machine code.
In C++ you can find yourself quickly entrenched in higher levels of abstraction. It's good for productivity but not necessarily so for understanding.
So my advice is: study C++ if you have the motivation, but first concentrate on the core low level constructs that are common with C. Only then move to the higher level things such as object orientation, templates, extensive class libraries and so on.
optimization theory
primarily because the asm output of a C compiler is generally mush more predictable and usually well correlated to the C. This lets you teach/learn why its better to structure code a certain way by showing the actual instructions generated.
You should learn data structures in C. First, it will force you to really understand pointers, which will help you to deal with leaky abstractions in higher level languages. Second it will make obvious the benefits of OO.
Coding Sytle
By coding style I don't mean {} and whitespace, I mean how you organizing data, classes, files, etc.
I started off learning c++, which usually favors creating classes and organizing things a certain way. I could write c code just fine when needed, but it was never like the c style code that others wrote who started off with c.
One of my OS classes required us to write a file system in C. My partner was originally a C guy and I was amazed at the difference in the code we wrote. Mine was obviously trying to use c++ style coding in c.
It's kindof like when you first learn perl or ruby or something and you are just trying to write the same c# code except translated into that new language rather than using that languages features.
While C is a subset of C++, C programs and C++ programs are so different as to not really be comparable.
Yes, simple structured programming.
With OOP everywhere, it is easy to forget that you can build sound system just by using modules and functions. C's module system is pretty weak, but still...
This is also one of the advantages of functional programming, in my book. Many functional programming languages have a strong module system. When you need more genericity than simple functions can offer, there are always higher order functions.
if you want to learn new skills and you have good fundamentals of structured programing(SP) you should go for C++. learn to think a given problem in an object oriented(OOP) way (define objects, methods, Inheritance, etc) its sometimes the most difficult part. I was in the same situation as you a few years ago, and i choose C++, because learning a new paradigm, a new way of thinking and design software, sometimes its more difficult that the code itself, and if you don't like C++ or OOP you can go back to C and SP, but at least you will have some OOP skills.
I would choose C to learn low-level primitives of programming.
For OOP, there are so many other languages to learn before C++ that are much easier to learn. This isn't 1990 when the only OOP languages were Smalltalk and C++, and only C++ was used outside of academia. Almost every new programming language invented since has objects, and almost all are less complex than C++.

For C/C++, When is it beneficial not to use Object Oriented Programming?

I find myself always trying to fit everything into the OOP methodology, when I'm coding in C/C++. But I realize that I don't always have to force everything into this mold. What are some pros/cons for using the OOP methodology versus not? I'm more interested in the pros/cons of NOT using OOP (for example, are there optimization benefits to not using OOP?). Thanks, let me know.
Of course it's very easy to explain a million reasons why OOP is a good thing. These include: design patterns, abstraction, encapsulation, modularity, polymorphism, and inheritance.
When not to use OOP:
Putting square pegs in round holes: Don't wrap everything in classes when they don't need to be. Sometimes there is no need and the extra overhead just makes your code slower and more complex.
Object state can get very complex: There is a really good quote from Joe Armstrong who invented Erlang:
The problem with object-oriented
languages is they’ve got all this
implicit environment that they carry
around with them. You wanted a banana
but what you got was a gorilla holding
the banana and the entire jungle.
Your code is already not OOP: It's not worth porting your code if your old code is not OOP. There is a quote from Richard Stallman in 1995
Adding OOP to Emacs is not clearly an
improvement; I used OOP when working
on the Lisp Machine window systems,
and I disagree with the usual view
that it is a superior way to program.
Portability with C: You may need to export a set of functions to C. Although you can simulate OOP in C by making a struct and a set of functions who's first parameter takes a pointer to that struct, it isn't always natural.
You may find more reasons in this paper entitled Bad Engineering Properties
of Object-Oriented Languages.
Wikipedia's Object Oriented Programming page also discusses some pros and cons.
One school of thought with object-oriented programming is that you should have all of the functions that operate on a class as methods on the class.
Scott Meyers, one of the C++ gurus, actually argues against this in this article:
How Non-Member Functions Improve Encapsulation.
He basically says, unless there's a real compelling reason to, you should keep the function SEPARATE from the class. Otherwise the class can turn into this big bloated unmanageable mess.
Based on experiences in a previous large project, I totally agree with him.
A benefit of non-oop functionality is that it often makes exporting your functionality to different languages easier. For example a simple DLL containing only functions is much easier to use in C#, you can use the P/Invoke to simply call the C++ functions. So in this sense it can be useful for writing extremely time critical algorithms that fit nicely into single/few function calls.
OOP is used a lot in GUI code, computer games, and simulations. Windows should be polymorphic - you can click on them, resize them, and so on. Computer game objects should be polymorphic - they probably have a location, a path to follow, they might have health, and they might have some AI behavior. Simulation objects also have behavior that is similar, but breaks down into classes.
For most things though, OOP is a bit of a waste of time. State usually just causes trouble, unless you have put it safely in the database where it belongs.
I suggest you read Bjarne's Paper about Why C++ is not just an Object-Oriented Programming Language
If we consider, for a moment, not object-orienatation itself but one
of the keystones of object-orientation: encapsulation.
It can be shown that change-propagation probability cannot increase
with distance from the change: if A depends on B and B depends on C,
and we change C, then the probability that A will change
cannot be larger than the proabability that B will
change. If B is a direct dependency on C and A is an indirect
dependency on C, then, more generally, to minimise the potential cost
of any change in a system we must miminimise the potential number of
direct dependencies.
The ISO defines encapsulation as the property that the information
contained in an object is accessible only through interactions at the
interfaces supported by the object.
We use encapsulation to minimise the number of potential dependencies
with the highest change-propagation probability. Basically,
encapsulation mitigates the ripple effect.
Thus one reason not to use encapsulation is when the system is so
small or so unchanging that the cost of potential ripple effects is
negligible. This is also, therefore, a case when OO might not be used
without potentially costly consequences.
Well, there are several alternatives. Non-OOP code in C++ may instead be:
C-style procedural code, or
C++-style generic programming
The only advantages to the first are the simplicity and backwards-compatibility. If you're writing a small trivial app, then messing around with classes is just a waste of time. If you're trying to write a "Hello World", just call printf already. Don't bother wrapping it in a class. And if you're working with an existing C codebase, it's probably not object-oriented, and trying to force it into a different paradigm than it already uses is just a recipe for pain.
For the latter, the situation is different, in that this approach is often superior to "traditional OOP".
Generic programming gives you greater performance (among other things because you often avoid the overhead of vtables, and because with less indirection, the compiler is better able to inline), better type safety (because the exact type is known, rather than hiding it behind an interface), and often cleaner and more concise code as well (STL iterators and algorithms enable much of this, without using a single instance of runtime polymorphism or virtual functions.
OOP is little more than an aging buzzword. A methodology that everyone misunderstood (The version supported by C++ and Java has little to do with what OOP originally meant, as in SmallTalk), and then pretended was the holy grail. There are aspects to it that are useful, certainly, but it is often not the best approach for designing an application.
Rather, express the overall logic by other means, for example generic programming, and when you need a class to encapsulate some simple concept, by all means design it according to OOP principles.
OOP is just a tool among many. The goal is not to write OOP code, but to write good code. Sometimes, the way to do this is by using OOP principles, but often, you can get better code using generic programmming principles, or functional programming.
It is a very project dependent decision. My general feel of OOP is that its useful for organizing large projects that involve multiple components. One area I find that OOP is especially pointless is school assignments. Excepting those specifically designed to teach OOP concepts, or large software design concepts, many of my assignments, specifically those in more algorithmy type classes are best suited to non-OOP design.
So specifically, smaller projects, that are not likely to grow large, and projects that center around a single algorithm seem to be non-OOP candidates in my books. Also, if you can write the specification as a linear set of steps, e.g., with no interactive GUI or state to maintain, this would also be an opportunity.
Of course, if you're required to use an OOP design, or an OOP toolkit, or if you have well defined 'objects' in you're spec, or if you need the features of polymorphism, etc. etc. etc...there are plenty of reasons to use it, the above seem to be indicators of when it would be simple not to.
Just my $0.02.
Having an Ada background, I develop in C in terms of packages containing data and their associated functions. This gives a code very modular with pieces of code that can be taken apart and reused on other projects. I don't feel the need to use OOP.
When I develop in Objective-C, objects are the natural container for data and code. I still develop with more or less the package concept in mind with some new cool features.
I'm used to be an OOP fanboy... Then realized using functions, generics and callbacks can often make a more elegant and change-friendly solution in C++ than classes and virtual functions.
Other big names realized it too: http://harmful.cat-v.org/software/OO_programming/
IMHO, I have a feeling that the OOP concept is not really suits the needs of the Big Data, as OOP assume all the stuff to be kept in memory (concept of Objects and member variables). This always result in memory demanding and heavy applications when OOP is used for example for big images processing. Instead, the simplicity of C maybe used with intensive parallel I/O making apps more efficient and easy to implement. It is the year 2019 I am writing this message...Everything may change in a year! :)
In my mind it comes down to what kind of model suits the problem at hand. It seems to me that OOP is best suited to coding GUI programs, in that the data and functionality for a graphical object is easily bundled together. Other problems- (such as a webserver, as an example off the top of my head), might be more easily modeled with a data centric approach, where there's no strong advantage to having a method and its data near each-other.
tl;dr depends on the problem.
I'd say the greatest benefit of C++ OOP is inheritance and polymorphism (Virtual function etc...) .
This allows for code reuse and extendibility
C++, use OOP - - - C, no, with certain exceptions
In C++ you should use OOP. It's a nice abstraction and it's the tool you are given. You either use it or leave it in the box where it can't help. You don't use the power saw for everything but I would read the manual and have it ready for the right job.
In C, it's a more difficult call. While you can certainly write arbitrarily object-oriented code in C, it's enough of a pain that you immediately find yourself fighting the language in order to use it. You may be more productive dropping the doesn't-fit-so-well design pattern and programming as C was intended to be used.
Furthermore, every time you make an array of function pointers or something in an OOP-in-C design pattern, you sever almost completely all visible links in the inheritance chain, making the code hard to maintain. In real OOP languages, there is an obvious chain of derived classes, often analyzed and documented for you. (mmm, javadoc.) Not so in OOP-in-C, and the tools available won't be able to see it.
So, I would argue in general against OOP in C. For a really complex program, you may well need the abstraction, and then you will have to do it despite needing to fight the language in the process and despite making the program quite hard to follow by anyone other than the original author.
But if you knew the program was going to become that complicated, you shouldn't have written it in C in the first place...
In C, there are some times when I 'emulate' the object oriented approach, by defining some sort of constructor with granular control over things like callbacks, when running several instances of it.
For instance, lets say I have some spiffy event handler library and I know that down the road I'm going to need many allocated copies:
So I would have (in C)
MyEvent *ev1 = new_eventhandler();
set_event_callback_func(ev1, callback_one);
ev1->setfd(fd1);
MyEvent *ev2 = new_eventhandler();
set_event_callback_func(ev2, callback_two);
ev2->setfd(fd2);
destroy_eventhandler(ev1);
destroy_eventhandler(ev2);
Obviously, I would later do something useful with that like handle received events in the two respective callback functions. I'm not going to really elaborate on the method of typing function pointers and structures to hold them, nor what would go on in the 'constructor' because its pretty obvious.
I think, this approach works for more advanced interfaces where its desirable to allow the user to define their own callbacks (and change them on the fly), or when working on complex non-blocking I/O services.
Otherwise, I much prefer a more procedural / functional approach.
Probably an unpopular idea but I think you should stick with non-OOP unless it adds something useful. In most practical problems OOP is useful but if I'm just playing with an idea I start writing non-object code and put functions and data into classes if it becomes useful.
Of course I still use other objects in my code (std::vector et al) and I use namespaces to help organise my functions but why put code into objects until it is useful? Equally don't shy away from free functions in an OO solution.
The question is tricky because OOP encompasses several concepts: object encapsulation, polymorphism, inheritance, etc. It's easy to take those ideas too far. Here's a concrete example:
When C++ first caught on, zillions of string classes sprung into being. Everything you could possibly imagine doing to a string (upcasing, downcasing, trimming, tokenizing, parsing, etc.) was a member function of some string class.
Notice, though, that std::strings from the STL don't have all these methods. STL is object-oriented--the state and implementation details of a string object are well encapsulated, only a small, orthogonal interface is exposed to the world. All the crazy manipulations that people used to include as member functions are now delegated to non-member functions.
This is powerful, because these functions can now work on any string class that exposes the same interface. If you use STL strings for most things and a specialty version tuned to your program's idiosyncracies, you don't have to duplicate member functions. You just have to implement the basic string interface and then you can re-use all those crazy manipulations.
Some people call this hybrid approach generic programming. It's still object-oriented programming, but it moves away from the "everything is a member-function" mentality that a lot of people associate with OOP.

C++11: a new language?

Recently I started reading (just a bit) the current draft for the future C++11 standard.
There are lots of new features, some of them already available via Boost Libs. Of course, I'm pretty happy with this new standard and I'd like to play with all the new features as soon as possibile.
Anyway, speaking about this draft with some friends, long-time C++ devs, some worries emerged. So, I ask you (to answer them):
1) The language itself
This update is huge, maybe too huge for a single standard update. Huge for the compiler vendors (even if most of them already started implementing some features) but also for the end-users.
In particular, a friend of mine told me "this is a sort of new language".
Can we consider it a brand new language after this update?
Do you plan to switch to the new standard or keep up with the "old" standard(s)?
2) Knowledge of the language
How the learning curve will be impacted by the new standard?
Teaching the language will be more difficult?
Some features, while pretty awesome, seem a bit too "academic" to me (as definition I mean). Am I wrong?
Mastering all these new additions could be a nightmare, couldn't it?
In short, no, we can't consider this a new language. It's the same language, new features. But instead of being bolted on by using the Boost libs, they're now going to be standard inclusions if you're using a compiler that supports the 0x standard.
One doesn't have to use the new standard while using a compiler that supports the new standard. One will have to learn and use the new standard if certain constraints exist on the software being developed, however, but that's a constraint with any software endeavor. I think that the new features that the 0x standard brings will make doing certain things easier and less error prone, so it's to one's advantage to learn what the new features are, and how they will improve their design strategy for future work. One will also have to learn it so that when working on software developed with it, they will understand what's going on and not make large boo-boos.
As to whether I will "switch to the new standard", if that means that I will learn the new standard and use it where applicable and where it increases my productivity, then yes, I certainly plan to switch. However, if this means that I will limit myself to only working with the new features of the 0x standard, then no, since much of my work involves code written before the standard and it would be a colossal undertaking to redesign everything to use the new features. Not only that, but it may introduce new bugs and performance issues that I'm not aware of without experience.
Learning C++ has always been one of the more challenging journeys a programmer can undertake. Adding new features to the language will not change the difficulty of learning its syntax and how to use it effectively, but the approach will change. People will still learn about pointers and how they work, but they'll also learn about smart pointers and how they're managed. In some cases, people will learn things differently than before. For example, people will still need to learn how to initialize things, but now they'll learn about Uniform Initialization and Initializer Lists as primary ways to do things. In some cases, perhaps understanding things will be easier with the addition of the new for syntax for ranges or the auto return type in a function declaration. I think that overall, C++ will become easier to learn and use while at the same time becoming easier to teach.
Mastering a language is a long-term goal, it can not be done over night. It's silly to think that one can have mastery over something as complex as C++ quickly. It takes practice, experience and debugging code to really hammer something in. Academically learning is one thing, but putting to use that knowledge is an entire different monster. I think that if one already has mastery of the C++ language, the new concepts will not pose too much of a burden, but a new comer may have an advantage in that they won't bother learning some of the more obsolete ways of doing things.
1) The language itself
As far as I'm aware, there are really no breaking changes between
C++'03 and C++'0x. The only one I can think of here relates to using
auto as a storage class specifier, but since it had no semantic
meaning I don't see that being an issue.
There are a lot of other academic fixes to the standard which are very
necssary, for example better descriptions for the layout of member
data. Finally, with multi-core/cpu architectures becoming the norm,
fixing the memory model was a must.
2) Knowledge of the language
Personally, I feel that for 99.9% of C++ developers the newer language is going to be easier to use. I'm specifically thinking of features such as auto, lambda's and constexpr. These features really should make using the language more enjoyable.
At a more advanced level, you have other features such as variadic
templates etc that help the more advanced users.
But there's nothing new here, I'm still surprised at the amount of
everyday C++ developers that haven't used (or even heard of) the STL.
From a personal perspective, the only feature I'm a bit concerned about in the new standard is that of concepts. As it is such a large change, the same problems that occurred with templates (ie. completely broken implementations) is a real danger.
Update post FDIS going out for voting:
As it happens, 'concepts' was dropped for C++ 0x and will be taken up again for C++ 1x. In the end there are some changes other than auto which could break your code, but in practise they'll probably be pretty rare. The key differences can be found in Appendix C.2 of the FDIS (pdf).
For me, one of the most important, will be:
unique_ptr + std::move() !
Imagine:
Smart pointer without any overhead:
no reference counting operations
no additional storage for reference counter variable
Smart pointer that can be moved, ie. no destructor/constructor calls when moved
What does this give you? Exception safe, cheap (pointers..) containers without any costs. The container will be able to just memcpy() unique_ptrs, so there will be no performance loss caused by wrapping regular pointer by smart pointer! So, once again:
You can use pointers
It will be safe (no memory leaks)
It will cost you nothing
You will be able to store them in containers, and they will be able to do "massive" moves (memcpy-like) with them cheaply.
It will be exception safe
:)
Another point of view:
Actually, when you move group of objects using copy(), there is constructor and destructor call for every object instance. When you copy 1000 objects of 1kb size, there will be at least one memcpy() and 2000 function calls.
If you would want to avoid the thousands of calls, you would have to use pointers.
But pointers are: dangerous, etc. Actual smart pointers will not help you, they solve other problems.
There is no solution for now. You must pay for C++ RAII/pointer/valuevars design from time to time. But with C++0x, using unique_ptr will allow to do "massive" moves of objects (yes, practically objects, because pointer will be smart) without "massive" constructor/destructor calls, and without risk of using pointers! For me, this is really important.
It's like relaxing the RAII concept (because of using pointers) without loosing RAII benefits. Another aspect: pointer wrapped in unique_ptr() will behave in many aspects similar to java reference object variable. The difference is that unique_ptr() will be able to exist in only one scope at a time.
Your friend is partially right but mostly wrong: it's the same language with extra features.
The good thing is, you don't have to master all the new features. One of the primary mandates for a standards body is to not break existing code, so you'll be able to go on, happily coding in your old style (I'm still mostly a C coder even though I do "C++" applications :-).
Only when you want to have a look at the new features will you need to bone up on the changes. This is a process you can stretch over years if need be.
My advice is to learn what all the new features are at a high level (if only to sound knowledgeable in job interviews) but learn the details slowly.
In some respects, C++0x should be easier to teach/learn than current C++:
Looping through a container - the new for syntax is far easier than for_each + functor or looping manually using iterators
Initialising containers: we'll be able to initialise sequences with the same syntax as arrays
Memory management: out goes dodgy old auto_ptr, in comes well-defined unique_ptr and shared_ptr
Lambdas, although necessarily more complex than other languages' equivalents, will be easier to learn than the C++98 process of defining function objects in a different scope.
Do you plan to switch to the new standard or keep up with the "old" standard(s)?
A year ago, I was writing strict C89, because the product in question was aggressively portable to embedded platforms, some of which had compilers with radically different ideas of which bits of C99 it's worth supporting. So a 20-year-old standard still hasn't been fully replaced by its 10-year-old successor.
So I don't expect to be able to get away from C++03 any time soon.
I do expect to use C++0x features where appropriate. Just as I use C99 features in C code, and gcc extensions in C and C++ (and would use MSVC extensions, although I've never worked on MSVC-only code for more than trivial amounts of time). But I expect it to be "nice to have" rather than baseline, pretty much indefinitely.
You have a point, but it's always been the case. There is a lot of C++ code out there that still doesn't incorporate anything from the '98 standard just because of the innate conservatism of some coders. Some of us remember a dark time before the std:: namespace (before namespaces, in fact), when everyone wrote their own string class, and pointers walked around naked all the time. There is a reason why we talk about "modern C++ style" - to distinguish from the earlier style because some people still have to maintain or update code in that style.
Any language has to evolve to survive, and any language that evolves will have a divided user base, if only because people vary in their attitude towards estimating opportunity costs in applying new language features to their own work.
With the advent of C++0x in shipping compilers, this conversation will be played out over and over in dev teams across the world:
YOUNGSTER: I've just discovered these things called lambdas! And I'm finding lots of ways to use them to make our code more expressive! Look, I rewrote your old Foo class, isn't that much neater?
OLDSTER: There was nothing wrong with my old Foo class. You're just looking for excuses to use a "cool" new feature unnecessarily. Why do you keep trying to make my life so complicated? Why do I keep having to learn new things? We need another war, that's what we need.
YOUNGSTER: You're just too stuck in your ways, old man, we shouldn't even be using C++ these days... if it was up to me -
OLDSTER: If it was up to me we'd have stuck with PL/1, but no... my wife had to vote for Carter and now we're stuck with all this object-oriented crap. There's nothing you can do with std::transform and lambdas that I can't do with a goto and a couple of labels.
etc.
Your programming career will always involve learning and re-learning. You can't expect c++ to stay the same till you retire and to be using the same methods and practises that you were using 40 years ago. Technology rolls on, and it rolls quickly. It's your job to keep up with it. Of course you can ignore that, and continue to work the same way you currently do, but in 5 / 10 years time you'll become so outdated that you'll be forced to learn it all then when you're trying to change job. And it will have been a lot easier to learn on the job all those years before :)
A few months ago I heard Bjarne Stroustrup give a talk titled 50 years of C++. Admittedly, I'm not a C++ programmer, but it seemed to me that he certainly doesn't think 0x is a new language!
Whether or not we can consider it a "new language", I think that's semantics. It doesn't make a difference. It's backwards compatible with our current C++ code, and it's a better language. Whether or not we consider it "the same language" doesn't matter.
About learning the language, remember that a lot of the new features are there to make the language easier to learn and use. Most of the features that add complexity are intended for library developers only. They can use these new features to make better, more efficient, and easier to use libraries, that you can then use without knowing about the features. Several of the changes actually simplify and generalize existing features, making them easier for newcomers to learn.
It is a big update, yes, but it is guided by a decade of experience with the current C++ standard. Every change is there because experience has shown that it is needed. In fact, the committee is being extremely cautious and conservative, and have refused a huge number of other language improvements. What is added here is only the fundamentals that 1) everyone could agree on, and 2) could be specified in time, without delaying the new standard.
It is not simply a few language designers sitting down and brainstorming new features they'd like to try.
Concepts and Concept Maps are going to greatly increase the grokability of template frameworks. If you've ever poured over the Boost source you'll know what I mean. You're constantly going from source to docs because the language just doesn't have the facilities to express template concepts. Hopefully Concepts + Duck Typing will give us the best of both worlds whereby entry points to template libraries can explicitly declare requirements but still have the freedom that Duck Typing provides when writing generic code.
There are lots of good things in C++0x, but they're mostly evolutionary changes that refine or extend existing ideas. I don't think it's different enough to justify calling it a "new language".