Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I've been programming in C++ for a while now, but mostly things centered around the low-level features of C++. By that I mean mostly working with pointers and raw arrays. I think this behavior is known as using C++ as C with classes. Despite this, I only having tried C recently for the first time. I was pleasantly surprised how languages like C# and Java hide these details away in convenient standard library classes like Dictionaries and Lists.

I'm aware that the C++ standard library has many containers like vectors, maps and strings as well and C++11 only adds to this by having std:: array and ranged loops.

How do I best learn to make use of these modern language features and which are suitable for which moments? Is it correct that software engineering in C++ nowadays is mostly free of manual memory management?

Lastly, which compiler should I use to make the most of the new standard? Visual Studio has excellent debugging tools, but even VS2012 seems to have terrible C++11 support.

share|improve this question
2  
I'd say calling VS2012's C++11 support "terrible" is a bit exaggerated, but it certainly could be better (missing initializer lists is especially annoying for test/toy code). But note that they announced that they will be shipping compiler updates independently of the rest of VS, so I guess we can hope for quite a few C++11 features in VS2012 in the course of 2013. –  Martin Ba Oct 23 '12 at 11:05
2  
At first I thought suggesting it for learning C++11 would be odd, but seeing that you are still stuck in C-With-Classes land... A decade ago I read Koenig/Moo's Accelerated C++. By the time I was actually already doing template meta-programming (I only read it for a review), but it still felt like a revelation. (I used it as a base for teaching C++ ever since.) Coming from C With Classes, the book can show you a whole new language you didn't know you had at your disposal. It's only 250 pages, and you can then quickly advance to something C++11-specific, but IMO it's a worthwhile step. –  sbi Oct 28 '12 at 20:39
2  
g++ -std=c++11 –  FredOverflow Jun 18 '13 at 18:43

4 Answers 4

up vote 41 down vote accepted

First, some rules of thumb:

  • Use std::unique_ptr as a no-overhead smart pointer. You shouldn’t need to bother with raw pointers all that often. std::shared_ptr is likewise unnecessary in most cases. A desire for shared ownership often betrays a lack of thought about ownership in the first place.

  • Use std::array for static-length arrays and std::vector for dynamic.

  • Use generic algorithms extensively, in particular:

    • <algorithm>
    • <numeric>
    • <iterator>
    • <functional>
  • Use auto and decltype() wherever they benefit readability. In particular, when you want to declare a thing, but of a type that you don’t care about such as an iterator or complex template type, use auto. When you want to declare a thing in terms of the type of another thing, use decltype().

  • Make things type-safe when you can. When you have assertions that enforce invariants on a particular kind of thing, that logic can be centralised in a type. And this doesn’t necessarily make for any runtime overhead. It should also go without saying that C-style casts ((T)x) should be avoided in favour of the more explicit (and searchable!) C++-style casts (e.g., static_cast).

  • Finally, know how the rule of three:

    • Destructor
    • Copy constructor
    • Assignment operator

    Has become the rule of five with the addition of the move constructor and move assignment operator. And understand rvalue references in general and how to avoid copying.

C++ is a complex language, so it’s difficult to characterise how best to use all of it. But the practices of good C++ development haven’t changed fundamentally with C++11. You should still prefer memory-managed containers over manual memory management—smart pointers make it easy to efficiently do this.

I would say that modern C++ is indeed mostly free of manual memory management—the advantage to C++’s memory model is that it’s deterministic, not that it’s manual. Predictable deallocations make for more predictable performance.

As for a compiler, G++ and Clang are both competitive in terms of C++11 features, and rapidly catching up on their deficiencies. I don’t use Visual Studio, so I can speak neither for nor against it.

Finally, a note about std::for_each: avoid it in general.

transform, accumulate, and eraseremove_if are good old functional map, fold, and filter. But for_each is more general, and therefore less meaningful—it doesn’t express any intent other than looping. Besides that, it’s used in the same situations as range-based for, and is syntactically heavier, even when used point-free. Consider:

for (const auto i : container)
    std::cout << i << '\n';

std::for_each(container.begin(), container.end(), [](int i) {
    std::cout << i << '\n';
});

for (const auto i : container)
    frobnicate(i);

std::for_each(container.begin(), container.end(), frobnicate);
share|improve this answer
5  
Are there some binding principles to these rules of thumb? It seems like a nice list of suggestions, but... As an outsider arriving to this question via Google, how does your answer help me pick up C++11 in a principled way, and use it without wrapping myself around the C++ axle? –  Robert Harvey Oct 22 '12 at 22:54
3  
+1 for the list, but I have a small nitpick: when (rightly) warning against std::for_each I would have expected the range based for loop as a better replacement than plain for. –  Fabio Fracassi Oct 23 '12 at 7:30
    
@FabioFracassi: Oops. I wrote plain to contrast with std::for_each, not with range-based. I’ve removed it to avoid confusion. –  Jon Purdy Oct 23 '12 at 17:47
1  
I would update if it wasn't for std::for_each(). When you have lambda, it's certainly better than a traditional for loop. With a range-based for loop that might not be the case, but you didn't write "range-based for loop". –  sbi Oct 28 '12 at 20:32
    
@sbi: In my mind, the term “for loop” includes “range-based for loop”. I have edited with more explanation and an example to clarify, thank you. –  Jon Purdy Oct 29 '12 at 14:17

As a starting point:

  • Stop using char* for strings. Use std::string or std::wstring and just watch your code get shorter, more readable, and safer
  • Stop using C-style arrays (things declared with [ ]) and use std::vector or some other appropriate container class. The nice things about std::vector are that it knows its own length, it cleans up its contents when it goes out of scope, it is easy to iterate over, and it makes itself bigger when you add more items. But there are other collections that might work even better for your circumstances.
  • Use std::unique_ptr - and learn std::move almost immediately. Since this may result in some noncopyable objects, laziness may occasionally send you towards std::shared_ptr - and you may have some genuine use cases for std::shared_ptr as well
  • Use auto when declaring iterators and types that depend on earlier declarations (eg earlier you declared a vector of something, now you're declaring a something, use auto)
  • Use algorithms and for_each over a "raw for" whenever you can since it spares others from reading your loop carefully to conclude that you're in fact iterating over the whole collection etc. If your compiler supports "range for" then use it over for_each. Learn trivial algorithm calls like iota, generate, accumulate, find_if and so on.
  • Use lambdas - they are the easy way to leverage algorithms. They also open the door to so much more.

Don't get too worked up about what compiler to use. The "terrible, awful" lack of C++ 11 support in VS2012 is that there isn't variadic templates (yeah right, you were just about to use variadic templates) and the {} initializer isn't there. I want that too but I'm hardly going to stop using a useful development tool over it.

The second thing to do, after embracing std::, is to start thinking RAII. Anytime you have

  • starting action
  • series of actions with something you got from starting action
  • cleanup action that needs to happen even in the case of exceptions

Then what you have is a constructor, a number of member functions, and a destructor. Write a class that takes care of that for you. You might not even have to write the ctor and the dtor. Putting a shared_ptr as a member variable of a class is an example of RAII - you don't write memory management code, but when your instance goes out of scope, the right things will happen. Expand that thinking to cover things like closing files, releasing handles, locks etc and code will just get simpler and smaller (while eliminating leaks) before your eyes.

If you're feeling really confident, purge printf in favour of cout, get rid of macros (#definestuff), and start learn some "advanced idioms" like PIMPL. I have a whole course on this at Pluralsight which you can probably watch using their free trial.

share|improve this answer
2  
I like how you are sarcastic about him not using variadic templates anytime soon, but I think missing uniform initialization is missing something really important for everyday programming. –  sbi Oct 28 '12 at 20:35
    
Can't wait for initializer lists ... waiting to find out when we'll get them ... –  Kate Gregory Oct 28 '12 at 20:37
    
Another important lack in VS2012 are "rvalue references v3", i.e. the automatic generated move constructor and move assign. –  Mr.C64 Oct 30 '12 at 21:56

How do I best learn to make use of these modern language features and which are suitable for which moments?

By programming. Experience is the best way to learn.

C++11 has lots of new features (auto, rvalue, new smart pointers - just to name few). The best start is to just start using them, and read about them whenever you can, and whenever you find an interesting article.

Is it correct that software engineering in C++ nowadays is mostly free of manual memory management?

That depends what you need to do. Most applications can get away with smart pointers, and forget about memory management. There are still applications that can not get away so easily (for example if they need placement new, or a custom memory allocator for whatever reason).

If you need to use Qt, you'll have to use their rules for memory management.

which compiler should I use to make the most of the new standard?

Whatever you have at hand that supports the latest standard :

but no compiler supports all features.

share|improve this answer

My university is still using C++ for teaching. I have programmed with C++ for 5 years and now I am a graduate student. Of course, now I am using a lot Java, Ruby etc. I really recommend you don't too hurry about those features in language like Java. In my experience and opinion, after the low level features of C++. You should look into topics like generic programming with C/C++ like making template class, template functions, operator overritten, virtual methods, smart pointers. For the Object Oriented Design Part, there are lots of features C++ have and Java does not, like multi-inheritance. Inheritance is powerful but dangerous too. The implementation level of object oriented design in C++ is a good topic too. Inter-process communication, threadings, are important in C++ too.

For the compiler and debugger. I know visual studio is awesome. But I really recommend you learn GDB, Valgrind, and Make still, and be good at these tools. Microsoft is awesome, but it did too many things for you. As a student, you really need to learn those things which Microsoft did too you. For the compiler, G++ is good from GNU.

After all, after so many years, I really feel, the most important things are the low level features like raw array. Vector is really just a dynamic array. These are my recommendations, something maybe too subjective, just take what you think is right.

share|improve this answer
5  
How does this answer the question? The question is not about learning C++ in general, but switching to C++11. –  Roc Martí Oct 23 '12 at 2:32

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.