You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Style guidelines are not overly strict. The important thing is that code is clear and readable with an appropriate amount of whitespace and reasonable length lines.
2 spaces indent level.
Tabs are not allowed, and a mixture of tabs and spaces is strictly forbidden. Modern autoindenting IDEs and editors require a consistent standard to be set.
// Good IdeaintmyFunction(bool t_b)
{
if (t_b)
{
// do something
}
}
{} are required for blocks.
Leaving them off can lead to semantic errors in the code.
// Bad Idea// this compiles and does what you want, but can lead to confusing// errors if close attention is not paid.for (int i = 0; i < 15; ++i)
std::cout << i << std::endl;
// Bad Idea// the cout is not part of the loop in this case even though it appears to beint sum = 0;
for (int i = 0; i < 15; ++i)
++sum;
std::cout << i << std::endl;
// Good Idea// It's clear which statements are part of the loop (or if block, or whatever)int sum = 0;
for (int i = 0; i < 15; ++i) {
++sum;
std::cout << i << std::endl;
}
Keep lines a reasonable length
// Bad Idea// hard to followif (x && y && myFunctionThatReturnsBool() && caseNumber3 && (15 > 12 || 2 < 3)) {
}
// Good Idea// Logical grouping, easier to readif (x && y && myFunctionThatReturnsBool()
&& caseNumber3
&& (15 > 12 || 2 < 3)) {
}
Unit Tests
<> vs ""
Safety
Use Exceptions Instead of Return Values
Avoid raw memory access
Raw memory access, allocation and deallocation are difficult to get correct in C++ without risking memory errors and leaks. C++11 provides tools to avoid these problems.
// Bad Idea
MyClass *myobj = new MyClass;
// ...delete myobj;
// Good Idea
std::shared_ptr<MyClass> myobj = make_shared<MyClass>();
// ... // myobj is automatically freed for you whenever it is no longer used.
Avoid global data
... this includes singleton objects
Global data leads to unintended sideeffects between functions and can make code difficult or impossible to parallelize. Even if the code is not intended today for parallelization, there is no reason to make it impossible for the future.
// Bad IdeaclassMyClass
{
public:MyClass(int t_value)
{
m_value = t_value;
}
private:int m_value;
};
// Good Idea// C++'s memeber initializer list is unique to the language and leads to// cleaner code and potential performance gains that other languages cannot // matchclassMyClass
{
public:MyClass(int t_value)
: m_value(t_value)
{
}
private:int m_value;
};
Performance
Prefer pre-increment to post-increment
... when it is semantically correct. Pre-increment is faster then post-increment because it does not require a copy of the object to be made.
// Bad Ideafor (int i = 0; i < 15; i++)
{
std::cout << i << std::endl;
}
// Good Ideafor (int i = 0; i < 15; ++i)
{
std::cout << i << std::endl;
}
Const as much as possible
const tells the compiler that a variable or method is immutable. This helps the compiler optimize the code and helps the developer know if a function side effects. Also, using const & prevents the compiler from copying data unnecessarily.
I just noticed that people are commenting on this gist. This file has not been maintained in many years. All of this has been moved to the much better organized online C++ Best Practices book.
I just noticed that people are commenting on this gist. This file has not been maintained in many years. All of this has been moved to the much better organized online C++ Best Practices book.
Very nice and detailed, thank you.