2013年8月1日星期四

Effective C++ notes (Rule 1 - Rule 10)

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;
}

沒有留言:

發佈留言