Rule 1: View C++ as a federation of language
view as 4 sub language
a) C
b) Object-oriented C
c) Template C++
d) STL
C++ Looks like 4 "sub-language" merge to form a language.
They are different => we should understand each "sub-language" behavior.
------------------------------------------------------
Rule 2: consts, enums and inlines to #define
Use: consts replace define
easy for symbol table look up, debug made easy, const = 1 copy only
class:
class c
{
 static const int a = 5;
};
For some of old compilers:
In header:
class c
{
 static const int v1;
}
In source:
const int c::v1 = 1;
Use enum:
class c
{
 enum {v1 = 1};
 int i[v1];
}
//can be found in template metprogramming
Use: template<typename T>
inline void CallWithMax(const T& a, const T& b)
{
 f(a>b?a:b);
}
not:
#define CALL_WITH_MAX(a,b) f((a)>b()?(a):(b))
-------------------------------------------------------------
Rule 3: Use const whenever possible
char greeting[] = "Hello";
char* p = greeting;   //non-const pointer, non-const data
const char* p = greeting; //non-const pointer, const data
char* const p = greeting; //const pointer, non-const data
const char* const p = greeting; //const pointer, const data
In other words,
const located at: (left)*, const data
const located at: *(right), const pointer
void f1(const Widget* pw);
is as same as
void f2(Widget const * pw);
iterator
const_iterator //cannot change value
logical-constness
mutable,prevent "bitwise-constness"
operator[] overload:
merge const operator[] and operator[]:
const cha& operator[] (std::size_t position)const
{
 return text[position];
}
char& operator[](std::size_t position)
{
 return
  const_cast<char&>(
   static_cast<const TextBlock&>(*this)[posiiton];
  )
}
-------------------------------------------------------------
Rule 4: Make sure that objects are initialized before they are used
ABEntry::ABEntry(const str::string& name, const std::string& address)
{
 theName = name;
 theAddress = address;
}
//Call theName, theAddress assignment
ABEntry::ABEntry():theName(),theAddress(),numTimesConsulted(0)
{
}
//call theName, theAddress constructor (run faster!)
static -> singleton design pattern, initialize and reference only one time.
-------------------------------------------------------------
Rule 5: Know what functions C++ silently writes and calls
class Empty
{
public:
 Empty(){...}
 Empty(const Empty& rhs){...}
 ~Empty(){...}
 Empty& operator=(const Empty& rhs){...}
};
cannot compile (generate implicate copy assignment) if the class has following conditions:
For the below cases, we must declare the copy constructor and assignment explicitly.
1) Reference
2) Const
3) base class copy assignment = private
-------------------------------------------------------------
Rule 6: Explicitly disallow the use of compiler-generated functions you do not want
1) Mark it as private
2) Do not implement it, declare only.
Private, derived from below class (Boost library - noncopyable class)
class Uncopyable
{
protected:
 Uncopyable(){}
 ~Uncopyable(){}
private:
 Uncopyable(const Uncopyable&);
 Uncopyable& operator=(const Uncopyable&);
}
class HomeForSale : private Uncopyable
{
}
-------------------------------------------------------------
Rule 7: Declare destructors virtual in polymorphic base classes
If the class is suppose not to be polymorphic, don't declare the class as virtual destructor.
-------------------------------------------------------------
Rule 8: Prevent exceptions from leaving destructor
The exception leave to outside world <- may cause undefined behavior / exit at earlier stage.
solution: explicit declare a function to let the user explicit "close" it.
The user call the "close" function with try{} catch{} case,
Equivalent:
Because the class has given the chance for the user explicit handle the exception, but the user didn't.
It is not the fault made by the class.
class cla
{
private:
 //......
 bool closed;
 
 void close()
 {
  //.....
  closed = true;
 }
 ~cla::cla()
 {
  if(!closed)
  {
   try
   {
    close();
   }
   catch()
   {
    //catch exception, log
   }
  }
 }
};
-------------------------------------------------------------
Rule 9: Never call virtual functions during construction or destruction
-------------------------------------------------------------
Rule 10: Have assignment operators return a reference to *this
because x=y=z=15;
equivalent x=(y=(z=15));
also apply in +=, -=, *=...etc operator.
Widget& operator+=(const Widget& rhs)
{
 //....
 return *this;
}
Widget& operator=(int rhs)
{
 //...
 return *this;
}
沒有留言:
發佈留言