20 Modern Visual C++ Best Practices!
This topic is a working space for the Tech Ed 2013 NA and Europe session "20 Modern Visual C++ Best Practices". It is based on information originally gathered in this thread in the Visual C++ MSDN forum. Please visit that thread for context and additional details.
You are encouraged to contribute. Here is how:
- Sign in to the Wiki. You may need to create an account.
- Click Edit. You must be signed in to the wiki.
- Add your tip to the appropriate theme/bucket. Provide supporting details including links to samples (or inline samples) as sub-items to your tip. Feel free to add more themes/buckets as needed.
- Click Save. Include an edit comment if you wish. You can also email-subscribe to updates to ensure you are alerted when changes are made.
The tips will be whittled down to the top 20 starting 5/13. This page will be updated to reflect the top 20. If you have any questions, ping ebattali@microsoft.com.
Coding
- Use const wherever possible (including object state)
- Prefer std::vector
- Uses contiguous memory
- Faster versus std::list and std::queue
- Use RAII
- Use smart pointers (no naked pointers)
- No raw delete
- Master synchronization
- Consider using non member C style functions contained within an anonymous namespace and implemented in the .cpp over private member functions declared on the class itself and visible in the header file
- std::string is also a container. Billy O’Neal, Microsoft. One thing I always tell people is to remember that std::basic_string is a Container in addition to being a string class. I see needlessly reimplementing things in because people don't see the thing they need in std::string or std::wstring's member function list.
- Use an appropriate pointer type. Jason Zink, MVP. Choose an appropriate pointer type for each situation (i.e. don't over-use smart pointers). While smart pointers are very useful for managing the lifetime of shared objects, their use does come at a cost when you iterate over many items and temporarily create and destroy the smart pointers. With properly designed and encapsulated objects (and their lifetimes), you can safely utilize naked pointers in many situations where performance is critical.
- Use range-for. Another nice addition in C++11 is range-based for loop. An interesting discussion on it and some usage patterns can be found here.
- Namespace trick. There is also an interesting trick by James McNellis on shortening namespace names (useful e.g. for WinRT, which has namespaces with very long names) here.
- Use type-rich programming. Matt P. Dziubinski. When growing containers : prefer "emplace" to "push_back" (it's better to construct in place instead of unnecessarily copying or even moving). Practice type-rich programming as here.
- Nesting STL containers with tuple eliminates error-prone code that implements new ADT. When growing such STL container of tuple use forward_as_tuple along-with emplace.
Debugging
- Use assert
- Use it with Direct X (to catch bad triangles)
- Compile with /W4 warning level to expose potential problems with your code that the compiler ignores with the default (/W3) setting. You can change this setting in the project's Property Pages under "Configuration Properties"->"C/C++"->"General". For added benefits, make sure you set the "Configuration:" to "All Configurations" and the "Platform:" to "All Platforms" before changing to /W4 so that you get the additional warning in all of the currently defined configurations and platforms.
As a Developer...
- Stay informed!
- Libraries
- Community
- Share your experience and knowledge
- Participate in forums, blogs and social media
- Join a user group and share what you know
- ...
Error Handling
- Distinguish between errors and nonerrors
- In Each Function, Give the Strongest Safety Guarantee that Won't Penalize Callers Who Don't Need It, But Always Give at Least the Basic Guarantee
- Prefer to Use Exceptions to Report Errors
Style
- Use a clear, deliberate, consistent style
- Comment for the next person to maintain your code (not for the comedy club)
- Understand what you have written; excessive complexity can more easily hide subtle bugs in C++ than in other languages.