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;
}
沒有留言:
發佈留言