一直都沒有系統地看過一次Effective C++,最近好好地完整地讀了一遍,收穫頗豐,把讀書筆記分享給你們看看,與你們交流交流~java
裏面抄了書上很多的內容,也有一些我的的理解,可能有誤,但願你們能及時指出~ios
class
Base
{
public
:
enum
{
Top
=
100
};
...
};
|
#define MAX(a, b) f((a) > (b) ? (a) : (b))
//當MAX(++a, b)時就出問題了
|
class
R
{...};
const
R
operator
*(
const
R
&
lhs
,
const
R
&
rhs
);
|
R a
,
b
,
c
;
(
a
*
b
)
=
c
;
//若是返回的不是const,編譯是能經過的
|
class
TextBlock
{
public
:
...
// operator[] for const對象
const
char
&
operator
[](
std
::
size_t position
)
const
;
// operator[] for non-const對象
char
&
operator
[](
std
::
size_t position
);
...
};
|
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
);
...
};
|
const
Rational
&
operator
*
(
const
Rational
&
lhs
,
const
Rational rhs
)
{
static
Rational result
;
result
=
...;
return
result
;
}
bool
operator
==
(
const
Rational
&
lhs
,
const
Rational
&
rhs
);
Rational a
,
b
,
c
,
d
;
if
((
a
*
b
)
==
(
c
*
d
))
{
// 這裏必定會是true的!
...
}
else
{
...
}
|
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
();
...
};
|