Better Code: Runtime Polymorphism - Sean Parent
http://sean-parent.stlab.cc/papers-and-presentations
http://sean-parent.stlab.cc/papers-and-presentations
- Write all code as a library.
- Reuse inceases your productivity.
- Writing unit tests is simplified.
Shared_ptr are just as good as global variable...
Value semantics
Reference semantics
- Polymorphc types:
- By using inheritance to capture polymorphc use, we shift the burden of use to the type implementation, tightly coupling components
- Inheritance implies variable size, which implies heap allocation.
- Heap allocation forces a further burden to manage the object lifetime.
- Indirection, heap allocation, and virtualization, impacts performance.
- Object lifetime management leads to garbage collection or reference counting.
- This encourages shared ownership and the proliferation of incidental data-structure.
- Shared ownership leads to synchronization issues, breaks local reasoning, and further impacts performance.
That is, inheritance is the base class of evil.
Guideline:
- Write classes that behave like regular objects to increase reuse.
- Do your own memory management, don't create garbage for your client to clean up.
Copy constructor guideline:
- The semantics of copy are to create a new object which is equal to, and logically disjoin from, the original.
- Copy constructor must copy the object. The compiler is free to elide copies so if the copy constructor does something else the code is incorrect.
- When a type manages remote parts it is necessary to supply a copy constructor.
- If you can, use an existing class(such as vector) to manage remote parts.
Assignment operator:
- Steal the guts of that copy!
- Assignment is consistent with copy. Generally:
T x; x=y; is equivalent to
T x = y;
- Assignment satisfying the strong exception guarantee is a nice property.
- Either complete successfully or throw an exception, leaving the object unchanged.
- Assignment (like all other operations) must satisfy the basic exception guarantee.
- Don't optimize for rare cases which impact common cases.
- Don't test for self-assignment to avoid the copy.
- The private implementation(Pimpl), or handle-body, idom is good for separating the implementation and reducing compile times.
- Pass sink arguments by value and swap or move into place.
- A sink argument is any argument consumed or returned by the function.
- The argument to assignment is a sink argument.
- However, because of a language defect, you must write a move assignment operator(explain below.)
Remember to provide move constructor!
- Provide a move constructor and move assignment to avoid copies and get fast permutations.
- Prior to C++11, provide a swap() function.
- Use '=default' when possible.
- Include the expected exception specification to catch mistakes.
Language defect:
- IFF data member or direct base class with a type that does NOT have a move assignment operator and is NOT trivially copyable, the type's defaulted copy/move assignment operator for class X is defined as deleted.
也就是,將一般的operator=(type x)
內容寫成movable並沒有用!
一定要有move assignment operator:
operator=(type&& x)
- Don't allow polymorphism to complicate the client code.
- Polymorphism is an implementation detail.
- The runtime-concept idiom allows polymorphism when needed without inheritance.
- A shared pointer to an immutable(const) object has value semantics.
- This is why passing arguments by const& works.
- Observation: Mutable polymorphism objects are the exception.
- Copy-on-write can be obtained using shared_ptr::unique()
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.