User:Feixie/C++/EffectiveC++

Rules

 * Disallow exception from leaving destructor, swallow it or abort

return *this so that you can cascad operator= detect self assignment make it exception safe (transactional, no side effect), using copy and swap.
 * operator

auto_ptr smart_ptr void func {	auto_ptr pRes(new Resource); .... }
 * RAII (resource acquisition is initialization)

functionA(functionB, auto_ptr(new Resrouce)) It includes three operations: functionB; new Resource; auto_ptr ctor; and you can't gaurentee the sequence, if they are invoked as new Resource -> functionB -> auto_ptr.ctor and exception happens in functionB, resource leak happens.
 * store newed object in smart pointer in standalone statement

forbid copying reference counting transfer underlying resource deep copy underlying resource
 * RAII Object copying policies


 * smart_ptr's customized deleter

make data members private so that you can make change to them w/o impacting client's code While we want to add an operation (function) to a class, prefer non-member to member. Adding public interface is exposing. If you need a function whose job can be done by existing interface, make it a non-member function.
 * Encapsulate

make it non-member function so that it can accept all convertable parameters. class A {...}; A operator*(const A& lth, const A& rth) {...}
 * operator*

template  class B{} template  B operator*(const B& lth, const B& rth) {...} //not working on convertable parameters we need declare it as friend class B put the definition into B's class

Define a high performance member swap function and a non-member swap function. name lookup rules (argument-dependent lookup) for functions is very useful.
 * classic specific non-throw swap with good performance.


 * postpone variable definition as late as possible

old format: (T)expr; T(expr); const_cast, reinterpret_cast, dynamic_cast, static_cast (forcing impliciate convertiong).
 * minimize casting:

basic promise: if exception happens, go to a valid state. strong promise: if exception happens, roll back. no-throw:
 * strive for exception safe

implicit inline: function definition inside class explicite inline: inline keywork inline exposes implementation to client code, any change to inline function may lead to client's code re-complication.
 * inline

depend on declaration rather than definition handle class (point to implementation) interface class (all functions are virtual and no data member)
 * minimize complie dependency

name lookup doesn't consider about signature. (diff between override and overload)
 * avoid name hidding

stop instantiating itself provide default behavior to derived class enforce derived class to implement it.
 * pure virtual function with implementation can

Non-virtual interface (Template Method Pattern) (public function call private virtual function) Strategy Pattern (tr1:function)
 * other options alike virtual function


 * default parameters of virtual function (Default parameters are resolved in compile time while virtual function is invoked in runtime)

implicite interface (interface is definied where it is used/invoked) compile-time polymorphism typename v.s. class: only difference is that typename must be used for nested dependent name. (e.g. T::dependent_name) Compiler assumes nested dependent name not a type and counts on you to use typename explicitly.
 * Template and GP

template  class Base {	public void funcA; }; template  class Deriv : public Base {	public void funcB {		using Base::funcA; funcA; // whether Base has funcA depends on the generated class. A specilazation of Base may has no method funcA. } }
 * Access names in templatized base class

typedef + function overloading
 * traits

if..else.. (function parameter overloading) while.. (recursive template deducing, e.g. enum)
 * template meta programming

class NewHandlerHolder {	public: NewHandlerHolder(std::new_handler nh) : _newHandler(nh){} private: std::new_handler _newHandler; NewHandlerHolder(const NewHandlerHolder&); NewHandlerHolder& operator=(const NewHandlerHolder& rth); }; template  class NewHandlerSupport {	public: operator new(size_t size_) {			NewHanlderHolder nhh(std::set_new_hanlder(newhandler)); ::operator new(size_); // if you wants to use your malloc, remember 1. handle size=0; 2. while loop for trying new_handler }	private: std::new_handler newHandler; };
 * operator new/delete and new_handler

void* operator new(size_t) throw (std::bad_alloc); void* operator new(size_t, void*) throw; void* operator new(size_t, const std::nothrow_t&) throw; If you want to define a new operator new like bellow: void* operator new(size_t, Logger&) throw(std::bad_alloc); YOU'D BETTER define a placement delete: void operator delete(void*, Logger&) throw;
 * placement new/delete