一直都没有系统地看过一次Effective C++,最近好好地完整地读了一遍,收获颇丰,把读书笔记分享给大家看看,与大家交流交流~
里面抄了书上不少的内容,也有一些个人的理解,可能有误,希望大家能及时指出~
#define
MAX(a, b) f((a) > (b) ? (a) : (b)) //当MAX(++a,
b)时就出问题了 |
class A {
public:
...
void print () const ;
...
};
extern A
a; |
class A {
public:
...
void print () const ;
...
};
A& a () {
static A
tmpa ;
return tmpa ;
} |
class DBConnection {
public:
...
static DBConnection
create ();
void close ();
}; |
class DBConn{
public:
...
~DBConn () {
db .close();
}
private:
DBConnection
db ;
}; |
~DBConn() {
try { db.close();}
catch (...) {
std ::abort();
}
} |
~ DBConn() {
try { db .close ();}
catch (...) {
}
} |
class DBConn{
public:
...
void close () {
db .close();
closed = true ;
}
~DBConn () {
if (! closed) {
try { db.close();}
catch (...) {
...
}
}
}
private:
DBConnection
db ;
bool closed ;
}; |
class Bitmap {};
class Widget {
...
Widget& Widget ::operator=(const Widget& rhs);
...
private:
Bitmap* pb ;
};
Widget& Widget ::operator=(const Widget& rhs) {
delete pb ;
pb = new Bitmap(*rhs.pb );
return *this;
} |
Widget& Widget ::operator=(const Widget& rhs) {
if (this == & rhs) return * this;
delete pb ;
pb = new Bitmap(*rhs.pb );
return *this;
} |
Widget& Widget ::operator=(const Widget& rhs) {
Bitmap* pOrig = pb;
pb = new Bitmap(*rhs.pb );
delete pOrig ;
return *this;
} |
Widget& Widget ::operator=(const Widget& rhs) {
Widget
temp (rhs);
swap(temp );
return *this;
} |
class my_ptr{
private:
A* pa ;
...
public:
...
operator A *() const {
return pa;
}
...
};
A* getA ();
my_ptr
ptr1(getA ());
...
A* p_tmp = ptr1 ; |
class A{};
int func();
void process(std::tr1 ::shared_ptr<A> pa , int ); |
process (std :: tr1:: shared_ptr <A >( new A ), func()); |
std::tr1 ::shared_ptr<A> pa (new A );
process(pa , func()); |
class Date {
public:
Date(int month, int day, int year);
...
}; |
class Date {
public:
Date(const Month& month , const Day& day , const Year& year );
...
}; |
Date
d(Month (1), Day(2 ), Year( 2013)); |
class Month {
public:
static Month
Jan () { return Month( 1);}
static Month
Feb () { return Month( 2);}
...
static Month
Dec () { return Month( 12);}
...
private:
explicit Month (int m);
...
}; |
class A {
public:
...
void func1 ();
void func2 ();
void func3 ();
...
}; |
class A {
public:
...
void func1 ();
void func2 ();
void func3 ();
void funcAll ();
...
}; |
void funcAllA(A& a ) {
a.func1 ();
a.func2 ();
a.func3 ();
} |
result = oneHalf * 2 ; //OK
result = 2 * oneHalf; //错误 |
namespace std {
template<typename T>
void swap (T& a, T& b ) {
T
temp (a);
a = b;
b = temp;
}
} |
class A {
public:
...
void swap (A& other) {
using std:: swap;
swap (pImpl, other.pImpl );
}
...
private:
AImpl* pImpl ; //实现类
};
namespace std {
template<> //全特化版本
void swap <A>( A& l, A & r) {
l .swap( r);
}
} |
namespace std {
template<typename T> //偏特化版本
void swap < A< T> >(A <T>& l, A<T >& r) {
l .swap( r);
}
} |
namespace std {
template<typename T>
void swap (A< T>& l, A <T>& r) {
l .swap( r);
}
} |
namespace MyWorld {
template<typename T>
void swap (A< T>& l, A <T>& r) {
l .swap( r);
}
} |
template<typename T>
void doSomething(T& a , T& b) {
using std ::swap;
...
swap(a , b);
...
} |
int doSomething() throw(); //
空白异常明细 |
class AImpl;
class A {
public:
...
private:
std::tr1 ::shared_ptr<AImpl> pImpl ;
}; |
class A {
...
static std ::tr1:: shared_ptr<A >
create (...);
...
}; |
class RealA: public A {
public:
...
private:
...
};
std::tr1 ::shared_ptr<A> A ::create(...) {
return std ::tr1:: shared_ptr<A >(new RealA (...));
} |
class Base {
private:
int x;
public:
virtual void mf1() ;
void mf1(int );
void mf3();
void mf3(double );
};
class Derived: public Base {
public:
using Base ::mf1;
using Base ::mf3;
virtual void mf1();
void mf3();
...
}; |
class Derived: public Base {
public:
virtual void mf1()
{ Base ::mf1(); }
...
}; |
class GameCharacter {
public:
int healthValue () const {
...
int retVal = doHealthValue();
...
return retVal;
}
private:
virtual int doHealthValue () const {
...
}
}; |
class A {
public:
void f(){
cout << "A" << endl;
}
};
class B: public A {
public:
void f() {
cout << "B" << endl;
}
};
int main() {
B t;
B* pb = & t;
A* pa = & t;
pa->f (); //调用A的f()
pb->f (); //调用B的f()
return 0;
} |
class A {
public:
virtual void f(char c = ‘A‘){
cout << "this
is A: " ;
cout << c << endl;
}
};
class B: public A {
public:
virtual void f(char c = ‘B‘) {
cout << "this
is B: " ;
cout << c << endl;
}
};
int main() {
A* p = new B;
p->f (); //调用B的f(),缺省参数来自A,结果是
//this
is B: A
return 0;
} |
class File {...}
class InputFile: public File {...}
class OutputFile: public File {...}
class IOFile: public InputFile , public OutputFile {...} |
class File {...}
class InputFile: virtual public File {...}
class OutputFile: virtual public File {...}
class IOFile: public InputFile , public OutputFile {...} |
template<typename T> class MakeFinally {
private: //构造函数与析造函数都在private,只有友员可以访问
MakeFinally(){};
~MakeFinally (){};
friend T;
};
//
MyClass是MakeFinally<MyClass>的友员,能实现初始化
class MyClass: public virtual MakeFinally <MyClass> {};
//
D不是MakeFinally<MyClass>的友员,不能访问private,而D继承的
//
是virtual base
class,必须得访问MakeFinally<MyClass>中的构造
//
因此,不能通过,
class D: public MyClass{};
int main() {
MyClass var1;
D var2; //
到这里就会出错,注释掉不会报错,因为定义为空,
//
被编译器忽略了
} |
template<typename T>
void doProcessing(T& w ){
if (w. size() > 10 && w != something ) {
T
temp (w);
w .normalize();
temp .swap( w);
}
} |
template<typename C>
void print( const C& c) {
//
没有typename是通不过编译的
typename C ::const_iterator
iter(c.begin ());
...
} |
class CompanyA {
public:
...
//
发送明文
void sendCleartext (const std ::string
msg);
//
发送密文
void sendEncrypted (const std ::string
msg);
...
};
class CompanyB {
public:
...
void sendCleartext (const std ::string
msg);
void sendEncrypted (const std ::string
msg);
...
};
template<typename Company>
class MsgSender {
public:
...
void sendClear (const std ::string
msg) {
Company
c ;
c .sendCleartext(msg);
}
void sendSecret (const std ::string
msg)
{...}
}; |
template<typename Company>
class DerivedMsgSender: public MsgSender <Company> {
public:
...
void sendClearMsg (const std ::string& msg) {
sendClear(msg); //这样是编译不过的!
}
}; |
class CompanyZ {...};
template<>
class MsgSender<CompanyZ> {
public:
...
//
只能传密文,不能传明文
void sendSecret (const std ::string& msg)
{...}
...
}; |
template <typename Company >
class DerivedMsgSender : public MsgSender < Company > {
public :
...
void sendClearMsg ( const std :: string& msg ) {
this->sendClear ( msg);
}
}; |
template<typename Company>
class DerivedMsgSender: public MsgSender <Company> {
public:
using MsgSender <Company>::sendClear;
...
void sendClearMsg (const std ::string& msg) {
sendClear (msg);
}
}; |
template<typename Company>
class DerivedMsgSender: public MsgSender <Company> {
public:
...
void sendClearMsg (const std ::string& msg) {
MsgSender<Company>::sendClear(msg );
}
}; |
class Top{...};
class Middle: public Top {...};
class Bottom: public Mid {...};
Top* pt1 = new Middle;
Top* pt2 = new Bottom;
const Top* pct2 = pt1 ; |
SmartPtr<Top > pt1 = SmartPtr<Middle >(new Middle );
SmartPtr<Top > pt2 = SmartPtr<Bottom >(new Bottom );
SmartPtr<const Top> pct2 = pt1; |
template<typename T>
class SmartPtr {
public:
template<typename U> //
成员函数模板
SmartPtr(const SmartPtr<U >& other)
:heldPtr(other.get ()) {...}
T* get () const { return heldPtr :}
private:
T* heldPtr ;
}; |
template<class T>
class shared_ptr {
public:
//
copy构造
shared_ptr(shared_ptr const& r );
// 泛化 copy构造
template<class Y>
shared_ptr(shared_ptr <Y> const & r);
//
copy assignment
shared_ptr& operator=(shared_ptr const& r );
// 泛化 copy
assignment
template<class Y>
shared_ptr& operator=(shared_ptr <Y> const & r);
}; |
template<typename T>
class Rational {
public:
Rational(const T& num = 0;
const T& den = 1);
const T
num () const ;
const T
den () const ;
...
};
template<typename T>
const Rational<T> operator* (const Rational <T>& lhs,
const Rational<T>& rhs )
{...}
Rational<int > oneHalf(1, 2);
Rational<int > result = oneHalf * 2; //编译不过 |
template<typename T>
const Rational<T> doMultiply (const Rational & lhs,
const Rational& rhs);
template<typename T>
class Rational {
public:
...
friend const Rational <T> operator* (const Rational<T>& lhs ,
const Rational<T>& rhs )
{
return doMultiply(lhs, rhs );
}
}; |
struct input_iterator_tag {};
struct output_iterator_tag {};
struct forward_iterator_tag: public input_iterator_tag {};
struct bidirectional_iterator_tag: public forward_iterator_tag {};
struct random_access_iterator_tag: public bidirectional_iterator_tag {}; |
template <typename IterT >
struct iterator_traits {
typedef typename IterT:: iterator_category
iterator_category ;
...
};
template<typename IterT> //对指针类型的特化,认真学习下
struct iterator_traits<IterT*> {
typedef random_access_iterator_tag
iterator_category ;
...
}; |
template<...>
class deque {
public:
class iterator {
public:
typedef random_access_iterator_tag
iterator_category;
...
};
...
};
template<...>
class list {
public:
class iterator {
public:
typedef bidirectional_iterator_tag
iterator_category;
...
};
...
}; |
template <typename IterT , typename DistT>
void advance (IterT & iter , DistT
d ) {
if ( typeid (typename std:: iterator_traits <IterT >:: iterator_category )
== typeid ( std:: random_access_iterator_tag ))
...
} |
template<typename IterT, typename DistT>
void doAdvance(IterT& iter , DistT
d,
std::random_access_iterator_tag) {
iter += d ;
}
template<typename IterT, typename DistT>
void doAdvance(IterT& iter , DistT
d,
std::bidirectional_iterator_tag) {
if (d >= 0 ) { while (d --) ++ iter}
else {while (d++) --iter;}
}
template<typename IterT, typename DistT>
void doAdvance(IterT& iter , DistT
d,
std::input_iterator_tag) {
if (d < 0 ) {
throw std:: out_of_range("Negative
distance" );
}
while (d--) ++iter;
}
template<typename IterT, typename DistT>
void advance(IterT& iter , DistT
d) {
doAdvance(
iter , d,
typename std:: iterator_traits<IterT >::iterator_category
);
//
书中版本为
//
doAdvance(
// iter,
d,
// typename
std::iterator_traits<IterT>::iterator_category()
//
);
//
个人觉得有误。也未查证英文原版 } |
template <typename IterT , typename DistT>
void advance (IterT & iter , DistT
d ) {
if ( typeid (typename std:: iterator_traits <IterT >:: iterator_category )
== typeid ( std:: random_access_iterator_tag ))
...
} |
std::list <int>:: iterator
iter;
...
advance(iter , 10 ); |
void advance(std::list <int>:: iterator& iter , int d) {
if (typeid(typename std:: iterator_traits< std ::list< int>::iterator >::iterator_category)
== typeid (std:: random_access_iterator_tag))
{...}
else
{...}
} |
template<unsigned n>
struct Factorial {
enum { value = n * Factorial<n -1>:: value };
};
template<>
struct Factorial<0> {
enum {value = 1 };
};
int main() {
std::cout << Factorial<5>::value ; //
打印:120
std::cout << Factorial<10>::value ; //
打印:3628800
} |
namespace std {
typedef void (* new_handler)();
new_handler
set_new_handler (new_handler
p) throw();
} |
#include
<iostream>
#include
<new> //
set_new_handler
#include
<cstdlib> //
abort
using namespace std;
void outOfMem() {
cerr << "out
of mem" << endl;
abort();
}
int main() {
set_new_handler(outOfMem );
int* data = new int [10000000000000L];
return 0;
} |
class Widget {
public:
static std ::new_handler
set_new_handler(std::new_handler
p ) throw ();
static void* operator new(size_t
size) throw ( bad_alloc);
private:
static std ::new_handler
currentHandler;
}; |
std::new_handler
Widget ::currentHandler = 0; |
std::new_handler
Widget ::set_new_handler(std::new_handler
p ) throw () {
std::new_handler
oldHandler = currentHandler;
currentHandler = p ;
return oldHandler ;
} |
T
is a static member (even if not
explicitly declared static
).
class NewHandlerHolder {
public:
explicit NewHandlerHolder (std:: new_handler
nh):handler (nh){}
~NewHandlerHolder () { std::set_new_handler (handler);}
public:
std::new_handler
handler ;
//
阻止copying,见条款14
NewHandlerHolder (const NewHandlerHolder & nh){}
NewHandlerHolder & operator =(const NewHandlerHolder & nh){}
};
void* Widget ::operator new(std ::size_t
size) throw(std::bad_alloc ) {
NewHandlerHolder h (std:: set_new_handler(currentHandler ));
return ::operator new(size );
} |
void outOfMem();
Widget::set_new_handler (outOfMem);
Widget* pw1 = new Widget;
std::string * ps = new std::string ;
Widget::set_new_handler (0);
Widget* pw2 = new Widget; |
template<typename T>
class NewHandlerSupport {
public:
static std ::new_handler
set_new_handler(std::new_handler
p ) throw ();
static voie * operator new(std:: size_t
size) throw(std ::bad_alloc);
private:
static std ::new_handler
currentHandler;
};
template<typename T>
std::new_handler
NewHandlerSupport<T >::set_new_handler(std::new_handler
p ) throw () {
std::new_handler
oldHandler = currentHandler;
currentHandler = p ;
return oldHandler ;
}
template<typename T>
void* NewHandlerSupport <T>:: operator new (std:: size_t
size)
throw(std ::bad_alloc)
{
NewHandlerHolder h (std:: set_new_handler(currentHandler ));
return ::operator new(size );
}
template<typename T>
std::new_handler
NewHandlerSupport <T>:: currentHandler = 0; |
class Widget: public NewHandlerSupport <Widget> {
... //
这样就不需要再声明set_new_handler和operator new
}; |
class Widget {...}
Widget* pw1 = new Widget; //如果分配失败抛出bad_alloc
if ( pw1 == 0) ... //这个测试一定失败
Widget* pw2 = new (std::nothrow ) Widget; //如果分配失败返回0
if ( pw2 == 0) ... //这个测试可能成功 |
Widget* pw = new Widget; |
//
正常的operator new
void* operator new (std:: size_t) throw(std ::bad_alloc);
//
正常的global作用域的operator delete
void operator delete(void* rawMemory) throw();
//
正常的class作用域的operator delete
void operator delete(void* rawMemory, std ::size_t
size) throw(); |
void* operator new (std:: size_t
size, void* pMemory ) throw (); |
class Widget {
...
//
带输出日志的new
static void* operator new(std::size_t
size , std:: ostream& logStream )
throw(std ::bad_alloc);
//
正常的class作用域的operator delete
static void operator delete(void * pMemory, std::size_t
size )
throw();
//
与带输出日志的new对应的delete
static void operator delete(void * pMemory, std::ostream & logStream)
throw();
...
}; |
Widget* pw = new (std::cerr ) Widget; //
是不是有点像条款49中nothrow的调用? |
delete pw; |
Widget* pw = new Widget;
// 错误
Widget * pw = new (std ::cerr ) Widget ;
// 正确 |
void* operator new (std:: size_t) throw(std ::bad_alloc); //
normal new
void* operator new (std:: size_t, void*) throw(); //
placement new
void* operator new (std:: size_t, const std:: nothrow_t&) throw();
//
nothrow new |
class StandardNewDeleteForms {
public:
//
normal new/delete
static void* operator new(std::size_t
size ) throw (std:: bad_alloc)
{return ::operator new(size);}
static void operator delete(void * pMemory) throw()
{::operator delete(pMemory);}
//
placement new/delete
static void* operator new(std::size_t
size , void * ptr) throw()
{return ::operator new(size, ptr );}
static void operator delete(void * pMemory, void* ptr) throw()
{::operator delete(pMemory, ptr );}
//
nothrow new/delete
static void* operator new(std::size_t
size , const std::nothrow_t & nt)
throw()
{return ::new(size, nt);}
static void operator delete(void * pMemory, const std ::nothrow_t&)
throw()
{::operator delete(pMemory);}
}; |
class Widget: public StandardNewDeleteForms {
public:
using StandardNewDeleteForms ::operator new;
using StandardNewDeleteForms ::operator delete;
static void* operator new(std::size_t
size , std:: ostream& logStream )
throw(std ::bad_alloc);
static void operator delete(void * pMemory, std::ostream & logStream)
throw();
...
}; |
Effective C++读书笔记,布布扣,bubuko.com
原文:http://www.cnblogs.com/flowerkzj/p/3583621.html