Effective C++ Learning Note 1
(undergradute edition)
===========================================
View C++ as a Federal of PL
SubLanguage
C
- Blocks
- Statements
- preprocessor: kind of instructions. started with ‘#’
- built-in date types
- arrays(basic DS)
- pointers
- no templates, exceptions, and overloading
OO C++
classic practice of OOP
- classes
- encapsulation
- inheritance
- polymorphism
- dynamic binding(virtual function)
Template C++——generic programming
- templates
- TMP(Template metaprogramming, 模板元编程) seldom intefere each other
STL
- containers
- iterators
- algorithms
- functionals
different preferences
An example:
- in C-like and STL: pass-by-value
- in OOC or TC: pass-by-reference-to-const
sum-up
Effective rules vary in the sublanguages.
Prefer consts, enums, and inline to '#define’s
prefer compiler to preprocessor
from #defines to const
main reasons
preprocessor replace; compiler could repace(better tail-after, more visulization)
if not, the replaced ones are difficult to watch and debug. Especially when it’s in another file written not by myself.
two cases of const
- const pointer.
const char* const kBloggerName = "Honour-Van"
- in-class consts
class GamePlayer{
private:
static const int NumTurns = 5; // only declaration
int scores[NumTurns]; // using the const
}
On condition that we need to take address or compiler wrongly insisted, we need:
const int GamePlayer::NumTurns;
Tips: we seldom initialize vars in classess, except for const
s
because we may declare several times, but only implement only once(during which we alloc the address to the vars.)
enum hack
if our attempt to initialize the const we stated above or use the static const to declare the array is FAILED(this is totally to blame for the foolish compiler), we can use the enum hack to compensate.
in the link on the runoob, enum hack is described as a seldom used technique.
advt:
- another kind of
static const int
var, without troubling CE. - quite like #define(which means no unecessary memry alloc to it, thus, we cannot take its address), but has infinite scope.
Macro functions
macros look like functions but that don’t incur the overhead of a function call.
but macro functions often made things foobar.
an awful example:
// call f with the maximum of a and b
#define CALL_WITH_MAX(a, b) f((a) > (b) ? (a) : (b));
int a = 5, b = 0;
CALL_WITH_MAX(++a, b); // a is incremented twice
CALL_WITH_MAX(++a, b+10); // a is incremented once
possible BEST
using inline template functions
template<typename T> // because we don't
inline void callWithMax(const T& a, const T& b)
// know what T is, we
{ // pass by reference-to
f(a > b ? a : b); // const
}
Use const
whenever possible
various usages in pointers
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
the only key is the order of const
and *
,
- if the former is prior, it means that we cannot change the data by the pointer;
- else: we cannot point the pointer to another place.
but the order of const and data type doesn’t count:
void f1(const Widget *pw); // f1 takes a pointer to a constant Widget object
void f2(Widget const *pw); // so does f2
iterators:
iterator | pointer declr | figurative |
---|---|---|
const <T>::iterator it |
T* const p |
target |
<T>::const_iterator cit |
const T* p |
camera |
const functions
mainly when dealing with the user-type
pass-by-param
- value: unnecessary
- pointer: we have discussed before
- pass-by-reference: user-type necessary(to cut the cost of copying)
return type
- built-in type: unnecessary
- const user-type: cannot be used as lval
- const pointer or const reference: somtimes useful
members
often used as interface.
if we want to change a specific member in the const function, you’d use the mutable
keyword
Initialization of Object(omitted)
- make sure local vars and user-class type vars be initialized.
- the constructing orders in the derived class.