array_view // void copy(array_view<const T> r, array_view<T> r2); // copy r to r2
// void copy_n(array_view<const T> p, array_view<T> q); // copy from p to q
string_view
owner<>
not_null<> // int length(not_null<const char*> p);
zstring // Use zstring and czstring to represent a C-style, zero-terminated strings.
Expects // Prefer Expects() for expressing preconditions
Ensures // Post condition
----------------
[[lifetime(this)]]
1.
Sometype iter; // default initialize if we haven't already
Someothertype success; // used these variables for some other purpose
tie( iter, success ) = myset.insert( "Hello" ); // normal return value
if (success) do_something_with( iter );
In some cases it may be useful to return a specific,
user-defined Value_or_error type along the lines of variant<T, error_code>,
rather than using the generic tuple.
2.
回傳 ptr 只有在回傳 position of a container or nullptr.
3.
class Handle { // OK
owner<Shape&> s; // use reference rather than pointer to prevent rebinding
// ...
public:
Handle(Shape& ss) : s{ss} { /* ... */ }
~Handle() { delete &s; }
// ...
};
對ref取址 就是 該 ref 真正reference到的object的位址。 等同於ptr本身。
4.
struct Rec2{
string s;
int i;
Rec2(const string& ss, int ii = 0) :s{ss}, i{ii} {} // redundant
};
POD可用 Type{a,b,c} 順序初始化內部的變數。
5.
By default, declare single-argument constructors explicit
6.
Use inheriting constructors to import constructors into a derived class that does not need further explicit initialization
class Rec {
// ... data and lots of nice constructors ...
};
class Oper : public Rec {
using Rec::Rec;
// ... no data members ...
// ... lots of nice utility functions ...
};
7.
Avoid self-assign check, let the library type do it by itself.
Foo& Foo::operator=(const Foo& a) // OK, but there is a cost
{
if (this==&a) return *this; // REMOVE THIS LINE!!!!
s = a.s; // if it's self-assign, it's ok, library type cope with this issue.
i = a.i;
return *this;
}
8.
For value-like types, consider providing a noexcept swap function
9.
Make == symmetric with respect to operand types and noexcept
10.
Make < symmetric with respect to operand types and noexcept
11.
Make a hash noexcept
12.
Use abstract classes as interfaces when complete separation of interface and implementation is needed.
Such as on an ABI (link) boundary.
13.
Redefine or prohibit copying for a base class; prefer a virtual clone function instead.
Copying a base is usually slicing. If you really need copy semantics,
copy deeply: Provide a virtual clone function that will copy the actual most-derived type,
and in derived classes return the derived type (use a covariant return type).
14.
Ensure all data members have the same access level
15.
Use multiple inheritance to represent multiple distinct interfaces
16.
Like other casts, dynamic_cast is overused. Prefer virtual functions to casting.
Prefer static polymorphism to hierarchy navigation where it is possible (no run-time resolution necessary) and reasonably convenient.
17.
Define operations on enumerations for safe and simple use
18.
Don't use ALL_CAPS for enumerators// clash with MACRO
19.
void fun( shared_ptr<Widget> sp1, shared_ptr<Widget> sp2 );
This fun can be called like this:
fun( shared_ptr<Widget>(new Widget(a, b)), shared_ptr<Widget>(new Widget(c, d)) ); // BAD: potential leak
20.
void sink(unique_ptr<widget>); // consumes the widget
void sink(widget*); // just uses the widget
21.
void share( shared_ptr<widget> ); // share – "will" retain refcount
void reseat( shared_ptr<widget>& ); // "might" reseat ptr
void may_share( const shared_ptr<widget>& ); // "might" retain refcount
22.
void reseat( unique_ptr<widget>& ); // "will" or "might" reseat pointer
BAD:
void thinko( const unique_ptr<widget>& ); // usually not what you want
23.
Keep common and local names short, and keep uncommon and nonlocal names longer
24.
Don't make claims about performance without measurements
25.
ccess memory predictably
Reason
Performance is very sensitive to cache performance and cache algorithms favor simple (usually linear) access to adjacent data.
Example
int matrix[rows][cols];
//bad
for(int c=0; c<cols; ++c)
for(int r=0; r<rows; ++r)
sum += matrix[r][c];
//good
for(int r=0; r<rows; ++r)
for(int c=0; c<cols; ++c)
sum += matrix[r][c];
26.
State your preconditions
State your postconditions
27.
Destructors, deallocation, and swap must never fail
28.
Use a final_action object to express cleanup if no suitable resource handle is available
Reason:
finally is less verbose and harder to get wrong than try/catch.
Example
void f(int n)
{
void* p = malloc(1, n);
auto _ = finally([p] { free(p); });
// ...
}
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.