You are on page 1of 232

++ .

, ,
.
, 
, ,
++. ,
++. ,
, !
, :


++
Bell Labs,

++ , 
,
,

.
++ Gotchas Pro
gramming in C++. 

The C++ Source,
C/C++ Users Journal, 
C++ Report. 
++ 


++.

ADDISONWESLEY

, 
++,
. , 
++.

"

ISBN13: 9785932860953
ISBN10: 5932860952

www.symbol.ru

(812) 3245353, (495) 9458100

C++.p65

: / C++
:

++

++,
++
++, 
, ++
Java, 
++
++

+
+

++

,
++, .

9 785932 860953

10.11.2007, 19:34

- -
Books.Ru
ISBN 978-5-93286-095-3 C++. - Books.Ru .
- ,

. ,
- (piracy@symbol.ru),
.

C++ Common Knowledge


Essential Intermediate Programming

Stephen C. Dewhurst

C++



2012

C++.
.

.

.
.
.
.
.
.
.

.
C++. . . . .: $, 2012. 240 ., .
ISBN 978$5$93286$095$3
, ++ 20$ ++
, , $
++,
. ,
, ,
++.
, C++
++ .
Java,
++
++ Java.
ISBN 9785932860953
ISBN 0321321928 ()
$, 2008, 2012
Authorized translation of the English edition 2005 Pearson Education Inc. This transla$
tion is published and sold by permission of Pearson Education Inc., the owner of all rights
to publish and sell the same.
,
. , $
, .

$. 199034, $, 16 , 7,
. (812) 380$5007, www.symbol.ru. N 000054 25.12.98.
26.12.2011. 70901/16 .
. 15 . .


. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

. . . . . . . . . . . . . . . . . . . . . . . . . . 29

, . . . . . . . . . . . . . . . . . . . . 32

. . . . . . . . . . . . . . . . . . . . . 35

. . . . . . . . . . . . . 38

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

10 $ . . . . . . . . . . . . . . . . . . . . . . . . . 48
11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
12 . . . . . . . . . . 55
13 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
14 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
15 . . . . . . . . . . . . . . . . 64
16 $ . . . . . . . . . . . . . . 67
17 . . . 70

18 $ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
19 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
20 $ STL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
21 . . . . . . . . . . . 84
22 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
23 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
24 $ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
25 , . . . . . . . . . . . . . . . . . . . . . . 96
26 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
27 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
28 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
29 . . . . . . . . . . . . . . . . . . . . 105
30 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108
31 . . . . . . . . . . . . . . . . . . . . . . . . 111
32 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
33 . . . . . . . . . . . . . . . . . . . . 115
34 . . . . . . . . . . . . . . . . . . . . . . . . . 118
35 new . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
36 . . . . . . . . . . . . . . . . . . . . . . 123
37 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
38 . . . . . . . . . . . . . . . . . . . . . . . . . 129
39 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
40 RAII . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
41 new, . . . . . . . . . . . . . . . . 139
42 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
43 auto_ptr . . . . . . . . . . . . . . . . . . . . . . 143
44 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145

45 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
46 . . . . . . . . . . . . . . . . . . . . . . 151
47 . . . . . . . . . . . . . . . . . . . . . . . 155
48 . . . . . . . . . . . . . . . . . . . . . 159
49
typename . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
50 $ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
51
template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
52 . . 173
53 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
54 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
55 $ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
56 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
57 . . . . . . . . . . . . . . . . . . . . . 195
58 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
59 SFINAE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
60 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
61 , . . . . . . . . . . . . . . . . . 210
62 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
63 . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219


, , ,
++.
. ++ $
,
.
, ,
. . ,
, , , $
.
++ ,
.
, .
, , . ,
. . ( $
) .
(Chuck Allison),
The C++ Source

++. 1982 1983. ,


,
(Bjarne Stroustrup) [ ++]
$ Bell Laboratories. $
, . , ,
. ,
. $
.
(Stan Lippman),
C++ Primer, Fourth Edition

$
.
. (Matthew P. Johnson),

[ ]. $

.
, , Effective C++
(Scott Meyers). $
.
(Moataz Kamel),
, Motorola,

. $
, ++ ( , ++).
(Clovis Tondo),
C++ Primer Answer Book


,
, .

, , .

,
,
, .
. .

C++ Report,
(Herb Sutter)
. $
.
, $
++. ,
, $
, , ,
.
C++, $
, . $
:

, C, $
C++ , , ;

12

, ,
C++, $
;

Java$,
C++ C++ Java;

C++
C++, $ $
, .

, ,
, $
C++, $
. , , C++ $
, ,
.
.
, $
C++, ,
. $
, $
C++. , $
, $
, .
, ,
, , $
, , . $
. $
, ;
$
.
. , , ,
, $
C++. , $
, ,
, , ,
C++.

C++ . $
, C++
.
( $
. , , ,

13

.) , $
, , $
. , , , C++
, ( )
,
. :
$
, $
.
.
C++.
,
void f( int );
void f( const char * );
//
f( "Hello" );

C++ , $
f . $
, .
$
C++.
, ; , $
, . C++,
,
. $
, .
, . $
. $
, , $
.
, $
(,
$,
).
, $
C++, $
(, $
$ ). ,
, , $
( ) , $
.

14

, , , , $
. ,
. $
, , .
.
, $
. ,
. , ,
( ) . $
$
.
C++ ,
( ) , $
.
, , , $
, ,
.
,
. $
, $
. , , $
, . $
, ,
, $
, .
,
.
, $
. , ,
,
,
. , .
,
, $
. $
, $
. , Heap, , $
, $
STL .
new $
, . $
, ,

15

. $
RAII
, $
$
,
.
.
, $

.
, $
, .
, $
$
. ,
, $
.
$
, , .
Shape, String, Stack . $

, . , ,
Shape, String.

.
,
$
C++. , $
. ( $
; $
, .) $

C++ .
C. ,
, , 2005


(Peter Gordon) $

C++,
$ . .
(Kim Boedigheimer) $
, .
(Matthew Johnson),
(Moataz Kamel), (Dan Saks), (Clovis
Tondo) (Matthew Wilson)
,
. , $
.

C/C++ Users Journal, $
$ Once, Weakly
semantics.org. $
, $
(Chuck Allison), (Attila Feher), (Kev$
lin Henney), (Thorsten Ottosen), , $
(Terje Slettebo), (Herb Sutter) (Leor
Zolman).

$
ADL .
(Brandon Goldfedder) $
, ,
,

17

. $
[5, 6, 7],
, ,
++
. $
. (Andrei Ale$
xandrescu)
. (Jack Reeves), $
, .

(Dick, Judy Ward),
$ , . ,
$
, ,
, , $
++ .
. (Sarah G. Hewins) . (David R. De$
whurst), , $
, .
$
, ,
. , , $
, , $
, . $
Addison$
Wesley . $
(Chanda Leary$Coutu)
$
$ .
(Molly Sharp) (Julie Nahil) $
Word ,
,
, $
. $
, (Richard Evans) $
. (Chuti
Prasertsith) $
. .


, .
$ , $
,
, . , 64
,
64.
, $
. $
. .

1 |
,
.
, ,
, . $
, ,
,
Employee (), Contract () PayrollRecord
( ). $
.
, ,
, .
,
C++, , Employee. $ $
, .
,
$
.
C++
. $
.
.
1. . , $
, ,
. .
,
.

20

2. , . $
, $
. (), $
(), ( ) $
(
).
get/set . $
, .
3. . (Scott Mey$
ers),
.
. , . $
$
, .
,
.
4. . $
. , $
. , $
, $
.

2 |

, , $
, C++. $
,
.
, .
,
.
AmOption ( ),
. 2.1.
AmOption :
AmOption, Option (), Deal () Priceable ( ).

. 2.1. .

22

(. 1
27 ), AmOption $
. ,
AmOption , Deal, Price
able Option. , AmOption $
. ,
AmOption,
, . ,
, (. 27 8
).
, . ,

. , ,
Option, AmOption, $
Option!
, AmOption Option. ($
, Option
.) $
(Option) .
:
$
, , $
, , $
$. ,
AmOption EurOption ( ), $
, ,
Option , . 2.2.

. 2.2. .
Option

23

, Option $
price (), Option, , AmOp
tion EurOption, . ,
Option , $
, $
.
, price
, . ,
:
AmOption *d = new AmOption;
Option *b = d;
d>price(); // AmOption::price...,
b>price(); // ... !

. ( , $
,
, .) :
? $
?, ,
.
, ,
:
b>update();
d>update();

// Option::update...,
// ... !

, , ,
$
, $
. , Am
Option EurOption, Option.
$
, Option.
$ AsianOption ( ), $
, Option, $
. ,
.
, , AmOption
EurOption, ,
. .
. $

. , $

24


(. 22 ).
$
, $
.
$ , ,
(. 29
30 ).

3 |
, ,
, $
, $ $
, , $
. $
, $
C++.
$
, $

. ,
. , $
, ,
.
.

. $, $
, $
. $, , $
,
.
. .
( , $
. , $
.) ,
: , $
.

26


. $
$
, .
, , $
, , $
, O(nlg2 n) , $
, $
. ,
( ), $
,
O(lg2 n) $
. $
$
, . $
,
,
, ,
.
$ $
, $
, .
,
, $
. , $$
, ,
. $
. $$
,
.
, ,
(Bridge), , $

. , ,
,
. $
, ,
, $
, . , $
.
$
.

27


( ), $
. ,
.
$, . $
, (wrapper) , $
. $
$
.
, $
, (Bridge),
(Strategy), (Facade), (Object Adapt$
er) . $
, $
, .
$, , $
. $
.
$, . $
$
, . $
,
, $
.
$,
. $
?
?
.
, , ,
, . $
? , .
, $
.

, $
, / , $

, .

28

,
$
. , ,
, , ,
.
$
. $
. $
$ ,
.
,
.
,
.
,
.

4 |
(Standard Template
Library STL) $
. , $
STL.
STL . $
.
STL : , $
. . $
. $
. ,
,
. STL , $
, , .
.
. ( ,
STL.) , $
, $
, ,
,
. STL

, , $
, (. 42
).
STL ,
. , $

30

$ $
. STL (, string, )
$
.
STL ,
(. 60 ). $
STL ,
.
, $
(
).
, .
,
. $
, ( ,
), $
. , $
, . ( $
C++ $
. . 2 , 30 , 19 8
60 .)
, , STL $
. $
$ (. $
20 8 STL), $ $
$
.
$
, , , $
.
STL . $$
$
(. 53 , 54
20 8 STL). ,
$ $
. , $

. $
STL ,
.
STL, , .

31

STL ,
. , STL
, $
. $
, , $
$
. , STL,
, ,
, $
, STL. , ,
, .
STL .

5 | ,

. ,
, , $
.
int a = 12;
int &ra = a;
ra;
a = 10;
int *ip = &ra;

//
//
//
//

ra a
a == 11
ra == 10
ip a

, , ,
C++ . $
, $.
: $
,
, .
ra a . $

.

:
Employee &anEmployee = *static_cast<Employee *>(0); // !

$
,
:

33

Employee *getAnEmployee();
//
Employee &anEmployee = *getAnEmployee(); //,
if( &anEmployee ==0 )
//

getAnEmployee ,
. $
getAnEmployee .
Employee *employee = getAnEmployee();
if( employee ) //...

, ,
, .
, : ,
. $
,
. ,
, . , $

. , $
. $
swap ()
a b :
template <typename T>
void swap( T &a, T &b ) {
T temp(a);
a = b;
b = temp;
}
//...
int x = 1, y = 2;
swap( x, y ); // x == 2, y == 1

swap a x, b y
. , , $
, . ,

.
int grades[MAX];
//...
swap( grades[i], grades[j] );

a b swap $
grades[i] grades[j] $

34


a b. .
, $
:
inline void set_2d( float *a, int m, int i, int j ) {
a[i * m + j] = a[i * m + j] * a[i * m + i] + a[i * m + j];

// !

!
, $
. ( ? .)
inline void set_2d( float *a, int m, int i, int j ) {
float &r = a[i * m + j];
r = r * r + r;
}

$
.
double &d = 12.3;
//!
swap( std::string("Hello"), std::string(", World")); // !

:
const double &cd = 12.3;
//OK
template <typename T>
T add( const T &a, const T &b ) {
return a + b;
}
//...
const std::string &greeting
= add(std::string("Hello"),std::string(", World"));

//OK

, $
, . $
, cd 12.3,
double, 12.3. $
greeting add
string. (. . $
) ,
.
, , $
, .

6 |

.
C/C++
, $
.
void average( int ary[12] );
//...
int anArray[] = { 1, 2, 3 };
const int anArraySize =
sizeof(anArray)/sizeof(anArray[0]);
average( anArray );

// int *
// 3
// == 3
// !

$
(decay). $
. , $
. , , $
, ,
,
. ( anArraySize
, $
.)
$
, , , .
($
), , , :
void average( int ary[] );

//  int *

36

, , ,
$
, :
void average( int (&ary)[12] );


12 .
average( anArray );

// ! anArray int [3]!

$ :
template <int n>
void average( int (&ary)[n] ); // n

.
void average_n( int ary[], int size );

, :
template <int n>
inline void average( int (&ary)[n] )
{ average_n( ary, n ); }

, $
,
$
, 88
(, '\0' $
, ). ,
, ,
.
,
.
int *anArray2 = new int[anArraySize];
//...
average( anArray2 ); // ! int(&)[n] int *
average_n( anArray, anArraySize ); // OK...


( vector
string), , ,
. (. Array 61
, .)

37


, ,
:
void process( int ary[10][20] );

, , $
.
, $
(. 17
44 ).
void process( int (*ary)[20] ); // ,
// 20 int

, ( ) $
, $
(. 44
). , , $
, , :
void process( int ary[][20] ); //  ,
//


, $
:
void process_2d( int *a, int n, int m ) {
for( int i = 0; i < n; ++i )
for( int j = 0; j < m; ++j )
a[i * m + j] = 0;
}

// a n m

// !

, .
template <int n, int m>
inline void process( int (&ary)[n][m] )
{ process_2d( &ary[0][0], n, m ); }

, $
. .

7 |

C++ $
. ,
.
T *pt = new T;
// T
const T *pct = pt; // T
T *const cpt = pt; // T

,
, : , $
, , . pct $
, , , $
; . . T,
*. cpt $
, . $
*, $
T.
,
(. . ,
*). , $
:
const T *p1; // T
T const *p2; // T

, C++ $
, .
,

39

T. ,
, , $

.
T const *p3;
//
T *const p4 = pt; //

, .
const T *const cpct1 = pt;
//
T const *const cpct2 = cpct1; //

,
:
const T &rct = *pt; // const T *const
T &rt = *pt;
// T *const

, $
. ,
pct ( const T *) pt ( T *).
, , ,
. , ,
(. 7.1).

. 7.1.

pct T, $
. ( )
:
void aFunc( const T *arg1, const T &arg2 );
//...
T *a = new T;
T b;
aFunc( a, b );

40

aFunc arg1 a arg2 $


b. , a $
b . ,
aFunc , $
, , .
.
$
, (. 7.2).

. 7.2.

pct , $
.
, pt
acT.
const T acT;
pct = &acT;
pt = pct; // ,
*pt = acT;

// !

C++ , $
. , ,
. , $
.
pt = const_cast<T *>(pct); // ,
*pt = aT;

// !

, $
pt , , acT,
(. 9 ).

8 |
. C++ $
.
int *pi;
int **ppi;
int ***pppi;

//
//
//

, $
.
.
Shape *picture[MAX];

// Shape


(. 6 ),
.
Shape **pic1 = picture;

, $
:
template <typename T>
class PtrVector {
public:
explicit PtrVector( size_t capacity )
: buf_(new T *[capacity]), cap_(capacity), size_(0) {}
//...
private:
T **buf_;
// T
size_t cap_;
//
size_t size_;
//

42

8
};
//...
PtrVector<Shape> pic2( MAX );

PtrVector,
. , .
$
.
, ,
:
void scanTo( const char **p, char c ) {
while( **p && **p != c )
++*p;
}

scanTo , $
. :
char s[] = "Hello, World!";
const char *cp = s;
scanTo( &cp, ',' ); // cp

C. C++ ,
$
, .
void scanTo( const char *&p, char c ) {
while( *p && *p != c )
++p;
}
//...
char s[] = "Hello, World!";
const char *cp = s;
scanTo( cp, ',' );

C++ $
.
: , $
, .
. , , $
:
Circle *c = new Circle;
Shape *s = c;
// ...

43

Circle () Shape (),


Circle Shape. $
Circle Shape:
Circle **cc = &c;
Shape **ss = cc;

// !

. ,

(. 7 8
), $
:
char *s1 = 0;
const char *s2 = s1; // OK...
char *a[MAX];
// char **
const char **ps = a; // !

9 |
. $
, $
$
. , $
. , C,
,
:
char *hopeItWorks = (char *)0x00ff0000; //

C++ . $
:
typedef char *PChar;
hopeItWorks =
PChar( 0x00ff0000 );

// /

, , ,
, .
, .
,
$
. , $
.
const_cast $
const volatile :
const Person *getEmployee() { ... }
//...

45

Person *anEmployee = const_cast<Person *>(getEmployee());

const_cast const
getEmployee. $
, :
anEmployee = (Person *)getEmployee();

const_cast . $,
. , , ,
. ,
.
, , $
. $, const_cast $
, ,
. $
,
. $
, , getEmp
loyee Person *. const_cast $
, const getEmp
loyee. (
), $ $
getEmployee:
const Employee *getEmployee();

// !

, , $
.
const Employee * Person *, , $
const_cast,
. , const_cast
, const_cast ,
.
static_cast $
. $

(. 27 8
):
Shape *sp = new Circle;
Circle *cp = static_cast<Circle *>(sp); //

static_cast , $
sp Circle. sp

46

$ Shape, cp , $
, . ,
, , .
, static_cast
, const_cast1. ,
,
, :
const Shape *getNextShape() { ... }
//...
Circle *cp =
static_cast<Circle *>(const_cast<Shape *>(getNextShape()));

reinterpret_cast, ,
, : $

:
hopeItWorks =
//
reinterpret_cast<char *>(0x00ff0000);
int *hopeless =
// char * int *
reinterpret_cast<int *>(hopeItWorks);

, $
.
. reinterpret_cast
static_cast
. reinterpret_cast
, $
, , static_cast ( $
, )
(. 28 ).
dyna
mic_cast. $

(., , 27 ). static_cast
dynamic_cast , $
(. .
) $
. $
1

++ const volatile $
static_cast,
static_cast (., , ISO IEC 14882 . 5.2.9).

47

. static_cast $
, dynamic_cast
.
const Circle *cp =
dynamic_cast<const Circle *>( getNextShape() );
if( cp ) { ... }

getNextShape Circle ( $ $
Circle , . . , Circle; . 2
), cp
Circle. cp . ,
:
if( const Circle *cp
= dynamic_cast<const Circle *>(getNextShape()) ) {...}

, cp $
if. , cp,
, .
dynamic_cast
:
const Circle &rc = dynamic_cast<const Circle &>(*getNextShape());

dynamic_cast,
,
std::bad_cast . (, $
; . 5 , .)
, dynamic_cast
( Shape Circle? , $
.), dynamic_cast
(, Shape , Cir
cle. , , $ !).
, $
dynamic_cast . $ $
.
30 .

10 |


$ .
.
this $ X
X *const. ,
X (. 7 ).
, this, ,
. this $ X $
const X *const X.
, this, , $
. $
$.

$,
.
X, , $
:
class X {
public:
X() : buffer_(0), isComputed_(false) {}
//...
void setBuffer() {
int *tmp = new int[MAX];
delete [] buffer_;
buffer_ = tmp;
}

49

void modifyBuffer( int index, int value ) const // !


{ buffer_[index] = value; }
int getValue() const {
if( !isComputed_ ) {
computedValue_ = expensiveOperation(); // !
isComputed_ = true;
// !
}
return computedValue_;
}
private:
static int expensiveOperation();
int *buffer_;
bool isComputed_;
int computedValue_;
};

$ setBuffer ,
X. modifyBuffer $
, X, , $
buffer_member.
, . ,
, , $
C++, $,
, $
( ). .
, $, ,
. $
, $
.
X::getValue $
.
$, X::getValue isCom
puted_ computedValue_ X. $
,
$ :
int getValue() const {
if( !isComputed_ ) {
X *const aThis = const_cast<X *const>(this);
aThis>computedValue_ = expensiveOperation();
aThis>isComputed_ = true;
}
return computedValue_;
}

// !

50

10

. ,
$ mutable:
class X {
public:
//...
int getValue() const {
if( !isComputed_ ) {
computedValue_ = expensiveOperation(); // ...
isComputed_ = true;
// ...
}
return computedValue_;
}
private:
//...
mutable bool isComputed_;
//
mutable int computedValue_; //
};

$ $
mutable, $
$ ( $).

$, , $
.
this $
,
$. $
:
class X {
public:
//...
int &operator [](int index);
const int &operator [](int index) const;
//...
};

, $
this. , $
X this:
int i = 12;
X a;
a[7] = i;
// X *const, a
const X b;
i = b[i];
// const X *const, b

51

$
this, .
$ $
:
X operator +( const X &, const X & );

$, $
,
$:
class X {
public:
//...
X operator +( const X &rightArg );

// !

X operator +( const X &rightArg ) const; // 


//...
};

C++ $
, $
, .

11 |
C $
, .
Java$ ,
, , C++
. $
C++
.
, . $
, C++ , $
,
. ( $
, $
C++ .) $
C++,
, ,
$
. ! $
, ,
, $
. $ $
.
. $

, $
. $
, ! $
, $

53

, $
? ?
. ,
C$, POD (plain old data
C). , POD ,
int, double , , C,
struct union.
struct S {
int a;
double b;
};

// POD

POD$ , $
C ( C++ $
, C). POD$
, $
C,
:
struct S {
// POD!
int a;
double b;
private:
std::string c; // ,
// POD
};

$
,
POD? ,
, .
, $
$.
, ,
, $
memcpy .
, (
35 new). $
$
. ,
, . .
$
.
,

54

11

. , $

.
. $
. (. 13 .)

$
. , $
, $
, ,
. , $
, .
struct T {
// POD
int a_;
// a_
virtual void f(); // vptr
};

,
, , , . $
,
, , !

12 |

, $
$.
. ,
$ . $
, ,
, .

, , , $
.
, int double, $
, (
. 5 , ):
int a = 12; // , 0X000C a
a = 12;
// , 0X000C a


. $
:
class String {
public:
String( const char *init ); // explicit
~String();
String( const String &that );
String &operator =( const String &that );
String &operator =( const char *str );
void swap( String &that );

56

12
friend const String
//
operator +( const String &, const String & );
friend bool operator <( const String &, const String & );
//...
private:
String( const char *, const char * ); //
char *s_;
};

. ,
,
.
String::String( const char *init ) {
if( !init ) init = "";
s_ = new char[ strlen(init)+1 ];
strcpy( s_, init );
}

, :
String::~String() { delete [] s_; }

, :
String &String::operator =( const char *str ) {
if( !str ) str = "";
char *tmp = strcpy( new char[ strlen(str)+1 ], str );
delete [] s_;
s_ = tmp;
return *this;
}

.
( this) $
(
str). String $
$
. 39 $
. ( , $ $
,
, new.
. .)
,
$
:
String *names = static_cast<String *>(::operator new( BUFSIZ ));

57

names[0] = "Sakamoto"; // ! delete []


// !

names () $
, operator new , $
String.
names , . $
String, $
. ($
, ,
35 new.)
, (. . $
, ),

(computational constructor):
const String operator +( const String &a, const String &b )
{ return String( a.s_, b.s_ ); }


String, .
String::String( const char *a, const char *b ) {
s_ = new char[ strlen(a)+strlen(b)+1 ];
strcat( strcpy( s_, a ), b );
}

13 |
$
. ,
.
class Impl;
class Handle {
public:
//...
Handle( const Handle & );
//
Handle &operator =( const Handle & ); //
void swap( Handle & );
//...
private:
Impl *impl_; // Handle
};

,
, . $
(., $
, 43 auto_ptr 32 8
). X
X(const X &), $
X &operator =(const X &). , , $
$ swap , $
swap $ $
, swap (). $
swap, , :
template <typename T>
void swap( T &a, T &b ) {

59

T temp(a); // T
a = b;
// T
b = temp; // T
}

swap ( swap ) $
T ,
T . $
. , Handle, :
.
inline void Handle::swap( Handle &that )
{ std::swap( impl_, that.impl_ ); }

, ,
? $, $
,
. $
swap. :
Handle &Handle::operator =( const Handle &that ) {
Handle temp( that ); //
swap( temp );
// swap
return *this;
// , temp
//
}

$, . . ,
$
. , $
swap
.
, $
.
, , $
.
Handle a = ...
Handle b;
b = a;
// a b

Handle a = ...
Handle b( a ); // b a

b
, $
.

60

13

$
, $
, ,
(. 35 8
new).
, , $
:
Handle &Handle::operator =( const Handle &that ) {
if( this != &that ) {
// ...
}
return *this;
}

, $
, ,
. . , (this) (that) $
.
C++ $
$
. , ,
. (. 29
).

14 |
.
void (*fp)(int); //

, ,
fp , void, void *
(. 17 8
). , $
.
extern int f( int );
extern void g( long );
extern void h( int );
//...
fp = f; // ! &f int(*)(int), void(*)(int)
fp = g; //! &g void(*)(long), void(*)(int)
fp = 0; // OK,
fp = h; // OK, h
fp = &h; // OK,

, $
. $
, ,
& .
,
, , $
:
(*fp)(12); //
fp(12);
// ,

62

14

, , $
, void *
. , $
$ ,
(. 16
8 ).

( $
18 8 19 ).
, $
, .
, ,
, :
extern void stopDropRoll();
inline void jumpIn() { ... }
//...
void (*fireAction)() = 0;
//...
if( !fatalist ) { // , ...
// !
if( nearWater )
fireAction = jumpIn;
else
fireAction = stopDropRoll;
}

, ,
, :
if( ftemp >= 451 ) {
if( fireAction )
fireAction();
}

// ...
// ... ...
// ... !

. $
,
$
, .
fireAction ( )
( ); , $
,
.
:
void jumpIn();

63

void jumpIn( bool canSwim );


//...
fireAction = jumpIn;

$
. fireAction void(*)(), $
, jumpIn ().

. $
set_new_handler. ,
, operator new $
.
void begForgiveness() {
logError( "Sorry!" );
throw std::bad_alloc();
}
//...
std::new_handler oldHandler =
std::set_new_handler(begForgiveness);

new_handler typedef:
typedef void (*new_handler)();

, , $
void. set_new_handler $
$
. .

:
std::new_handler current
= std::set_new_handler( 0 ); // ...
std::set_new_handler( current ); // ... !

set_terminate set_unexpected
.

15 |

.
.
( $
):
int *ip;
// int
int C::*pimC; // int C

, *, _::*,
_. $
.
void * * *const * weird1;
void *A::*B::*const * weird2;

weird1 $
void. weird2
B A, $
void. ( ,
.)
. $
, :
int a = 12;
ip = &a;
*ip = 0;
a = *ip;

, ,
. ,

65

. $
. ,
C++ , $
, .
$
, ,
. ( , $
0 .) ,
.
class C {
public:
//...
int a_;
};
int C::*pimC; // C int
C aC;
C *pC = &aC;
pimC = &C::a_;
aC.*pimC = 0;
int b = pC>*pimC;

pimC &C::a_, pimC


a_ C. . a_ , $
& &C::a_ , .
, C.
12 C,
12 C.
,
, . $
.* >*. pC>*pimC,
, pC, , pimC,
C,
pC. aC.*pimC, aC
, pimC, $
C, pC.
,
$, $
.
$
.
,
.
(. $

66

15

2 ). , , , $
, Circle () Shape () $
. ++ ,
Circle * Shape *. Shape * Circle * ,
. $
Shape, Circle. ( $
: .)
:
$
, $
$
. ,
, $
. .
class Shape {
//...
Point center_;
//...
};
class Circle : public Shape {
//...
double radius_;
//...
};

Circle Shape, , Shape


Circle. , Shape $
Circle.
Point Circle::*loc = &Shape::center_; // OK,

Shape Circle, ,
Circle Shape.
double Shape::*extent =
&Circle::radius_;

// !

, Circle $
Shape (. . Shape). C++
Shape Circ
le. , Shape Circle (Shape $
Circle). C++ , $
Circle Shape.

16 | 

$, ,
$.
class Shape {
public:
//...
void moveTo( Point newLocation );
bool validate() const;
virtual bool draw() const = 0;
//...
};
class Circle : public Shape {
//...
bool draw() const;
//...
};
//...
void (Shape::*mf1)( Point ) = &Shape::moveTo; //

$
, ($
, , ; . 17 8
). $
$, *, , $
, , , .
, ,
$ $:
bool (Shape::*mf2)() const = &Shape::validate;

68

16

$,
$, . $
$, , $
( $)
. $
, ( ; . 28
) this
, , .
Circle circ;
Shape *pShape = &circ;
(pShape>*mf2)(); // Shape::validate
(circ.*mf2)();
// Shape::validate

>* .* ,
, (). $
, , !

(a+b)*c, , , $
, .
, , $
$. $$
, , .
mf2 = &Shape::draw; // draw
(pShape>*mf2)();
// Circle::draw

, $
. $
$ $
:
$, ,
;
$
(. 11 );
this
(. 28 );
, .
$ $
, , $
. $

$
.

69

$, $ $
: $
$ $
$ , . ,
, $ $
this , $

, .
class B {
public:
void bset( int val ) { bval_ = val; }
private
int bval_;
};
class D : public B {
public:
void dset( int val ) { dval_ = val; }
private:
int dval_;
};
B b;
D d;
void (B::*f1)(int) = &D::dset; // !
//
(b.*f1)(12);
// ! dval!
void (D::*f2)(int) = &B::bset; // OK,
//
(d.*f2)(11);
// OK, bval

17 |


$
, .
.
int *f1();
// , int *
int (*fp1)(); // , int

,
:
const int N = 12;
int *a1[N];
// N int *
int (*ap1)[N]; // , N

, ,
:
int (**ap2)[N]; //
//
int *(*ap3)[N]; //
int (**const fp2)()
int *(*fp3)();

,
N int
, N int *
= 0; //
// , int *

, $
, .
char *(*fp4)(int,int);
char *(*fp5)(short,short) = 0;
fp4 = fp5;
// !

71

,
. $
:
int (*)()afp1[N]; // !

()
() , afp1 $
. :
int[N] a2;

// !

Java, C++. $

, . $
, :
int (*afp2[N])(); // N ,
// int

,
typedef.
typedef int (*FP)(); // int
FP afp3[N];
// N FP , afp2

typedef
,
. typedef set_
new_handler:
typedef void (*new_handler)();
new_handler set_new_handler( new_handler );

, new_handler (. 14 )
,
void. set_new_handler , new_handler $
new_handler. . ty
pedef, ,
, :
void (*set_new_handler(void (*)()))(); // ,

.
int aFunc( double );
//
int (&rFunc)(double) = aFunc; //

72

17

$
, :
int (*const pFunc)(double) = aFunc; //

$
, , $
6 .

18 | 
$,
. , ($
) . , $
$.
$, (. 42 8
), . $
> * (, , >*), $
(pointer on steroids, , $
), $ (),
. $
$, $
(1, 1, 2, 3, 5, 8, 13):
class Fib {
public:
Fib() : a0_(1), a1_(1) {}
int operator ()();
private:
int a0_, a1_;
};
int Fib::operator ()() {
int temp = a0_;
a0_ = a1_;
a1_ = temp + a0_;
return temp;
}

$ , ope
rator () ( , )
.

74

18
Fib fib;
//...
cout << "next two in series: " << fib() << ' ';
cout << fib() << endl;

fib() $ opera
tor() fib. fib.operator(), ,
, . $
$ , $
, $
, Fib.

$ . ,
. $
, , ,
,
Fib, .
int fibonacci () {
static int a0 = 0, a1 = 1; // ...
int temp = a0;
a0 = a1;
a1 = temp + a0;
return temp;
}


, $
operator().
, . 18.1.

. 18.1.
()

75

$
( )
, $
.
typedef double (*F)( double );
double integrate( F f, double low, double high ) {
const int numSteps = 8;
double step = (highlow)/numSteps;
double area = 0.0;
while( low < high ) {
area += f( low ) * step;
low += step;
}
return area;
}

, $
.
double aFunc( double x ) { ... }
//...
double area = integrate( aFunc, 0.0, 2.71828 );

, ,
.
,
$. $
$.
, operator().
class Func {
public:
virtual ~Func();
virtual double operator ()( double ) = 0;
};
double integrate( Func &f, double low, double high );

integrate $ $
, Func (. 2 ). $
, integrate ( $
), $$
, . ,
Func , , $
:
class NMFunc : public Func {
public:

76

18
NMFunc( double (*f)( double ) ) : f_(f) {}
double operator ()( double d ) { return f_( d ); }
private:
double (*f_)( double );
};

:
double aFunc( double x ) { ... }
//...
NMFunc g( aFunc );
double area = integrate( g, 0.0, 2.71828 );

$ ,
$ $
(. 16 8 ):
template <class C>
class MFunc : public Func {
public:
MFunc( C &obj, double (C::*f)(double) )
: obj_(obj), f_(f) {}
double operator ()( double d )
{ return (obj_.*f_)( d ); }
private:
C &obj_;
double (C::*f_)( double );
};
//...
AClass anObj;
MFunc<AClass> f( anObj, &AClass::aFunc );
double area = integrate( f, 0.0, 2.71828 );

19 |
$ ,
(Command).
? , $
. , ,
, $
, .
. ( $
,
), , , .
$
( ) ( ).
, $, , . ,
, , .
.
,
(. $
14 ). Button,

.
class Button {
public:
Button( const string &label )
: label_(label), action_(0) {}
~Button {... delete action_; ...}
void setAction( void (*newAction)() )
{ action_ = newAction; }
void onClick() const

78

19

{ if( action_ ) action_(); }


private:
string label_;
void (*action_)();
//...
};

Button
Button , $
.
extern void playMusic();
//...
Button *b = new Button( "Anoko no namaewa" );
b>setAction( playMusic );
registerButtonWithFramework( b );

:
, . $
. ,
.

. $
,
. playMusic ( )
, ? $
,

extern void playAnokoNoNamaewa();
//...
b>setAction( playAnokoNoNamaewa );

$
:
extern const MP3 *theCurrentSong = 0;
//...
const MP3 anokoNoNamaewa ( "AnokoNoNamaewa.mp3" );
theCurrentSong = &anokoNoNamaewa;
b>setAction( playMusic );

, $
. $ $
$
.

79

$
, $ . $
$
, . $
$ (. 18 88
). , . $
Button :
class Action {
//
public:
virtual ~Action();
virtual void operator ()() = 0;
virtual Action *clone() const = 0; //
};
class Button {
public:
Button( const std::string &label )
: label_(label), action_(0) {}
~Button {... delete action_; ...}
void setAction( const Action *newAction ) {
Action *temp = newAction>clone();
delete action_;
action_ = temp;
}
void onClick() const
{ if( action_ ) (*action_)(); }
private:
std::string label_;
Action *action_;
//
//...
};

Button $, $
Action, :
class PlayMusic : public Action {
public:
PlayMusic( const std::string &songFile )
: song_(songFile) {}
void operator ()();
//
//...
private:
MP3 song_;
};

( )
, $ PlayMusic.

80

19
Button *b = new Button ("Anoko no namaewa");
b>setAction (&PlayMusic ("AnokoNoNamaewa.mp3"));1

,
? ,
.
$
(Prototype) , $
(. 29 ).
, $
, ,
.

,
. :
PlayMusic pm (AnokoNoNamaewa.mp3);
b>setAction (&pm);

20 |  STL
STL?
, $
.
std::vector<std::string> names;
//...
std::sort( names.begin(), names.end() );

STL , $
.
string . $
, , $
.
class State {
public:
//...
int population() const;
float aveTempF() const;
//...
};

State ( )
. , ,
, ($
, , , $
, . .). , STL $
, .
, $
:
inline bool popLess( const State &a, const State &b )
{ return a.population() < b.population(); }

82

20

State, :
State states[50];
//...
std::sort( states, states+50, popLess ); //

popLess
(, 8
; states
). popLess
, sort, ,
(. 14 ).
, $
:
struct PopLess : public std::binary_function <State,State,bool> {
bool operator ()( const State &a, const State &b ) const
{ return popLess( a, b ); }
};

PopLess $
STL. $, $.
, $
. , $
STL, sort, , $
, $
$, ,
. $ operator() $
.
$, bi
nary_function. STL $
$ (. 53 8
). binary_
function $
$.
, ,
$ , , PopLess
.
$, $ $, $
, $
operator () .
STL $ , $
. $ STL $
, .
$ $$

* STL

83

, STL, ,
STL $
.
, .
$:
sort( states, states+50, PopLess() );

, PopLess
. PopLess ,
. Pop
Less, PopLess,
. ( 8
(anonymous temporary); $
.) $
:
PopLess comp;
sort( states, states+50, comp );

.
$ $
, , $
. $
: $
(Pop
Less), , ,
PopLess::operator () ,
popLess.
$ STL
. $
. (
.)
struct IsWarm : public std::unary_function<State,bool> {
bool operator ()( const State &a ) const
{ return a.aveTempF() > 60; }
};

STL $
STL, , ,
STL , .
State, $
$
:
State *warmandsparse = find_if( states, states+50, IsWarm() );

21 |

. . $
$
.
,
. $
(
).
,
, $
(. 24 8
8 25 , ).
.
, $
$
. $
,
. ,
( . 31 ).
:
class B {
public:
//...
virtual int f( int );
void f( B * );

85

//...
};

f B,
f. (
. , , $
, , $
. [2] [5] , $
.)
class D : public B {
public:
int f( int );
int f( B * );
};

$ D::f(int)
B::f(int). $ D::f(B *) , $
B::f(B *) .
D::f(int). , $
B::f,
(. 63 ).
. $
, $

.

22 |
(Template Method) $
C++. , $
$
(. 2 8
). ,
, ,
.

(. 3 ).

$.
$$
. $ $
(. 12
). $ , $
.
, $
, , $
,
. ,
, , $
. , $
, .
$ , $
. $

(. 24 8

87

8). , , $
, . $
.
, $
$
. , ,
,
$
(. . ) .
$
, .

$
,
.
, $
.
, . $
, $
, $
, $
, .
class App {
public:
virtual ~App();
//...
void startup() { //
initialize();
if( !validate() )
altInit();
}
protected:
virtual bool validate() const = 0;
virtual void altInit();
//...
private:
void initialize();
//...
};

startup , $
:

88

22
class MyApp : public App {
public:
//...
private:
bool validate() const;
void altInit();
//...
};

:
, (. 19 8
). startup $
. startup, , $
. , $
validate altInit. ,
validate altInit, . $
.

23 |
. $
,
. ,
String, , $
String,
$ .
( , $
) . .
$
(. 25 , ), $
. $
:
namespace org_semantics {
class String { ... };
String operator +( const String &, const String & );
// , , ....
}

org_semantics ,
$
. $ $
, .
.
, org_seman
tics , . , $
:
namespace org_semantics {

90

23

String operator +( const String &a, String &b ) { // !


//...
}
}

$
:
org_semantics::String
org_semantics::operator +(
const org_semantics::String &a,
const org_semantics::String &b ) {
//...
}

, $
( ,
const operator+). $
, org_semantics $
, ! $
, .
, $
, , $
:
org_semantics::String s( "Hello, World!" );

C++ $
( operator
new, operator delete, operator new[] operator delete[] $
),
std ( standard ). $

std:
#include <iostream>
#include <vector>
//...
void aFunc() {
vector<int> a;
std::vector<int> b;
cout << "Oops!" << endl;

// ! !
// , !
// !

std::cout << "Better!" << std::endl; // OK


//...
}

91

, $
. using.
void aFunc() {
using namespace std;
// using
vector<int> a;
// OK
cout << "Hello!" << endl; // OK
//...
}

using () $
, $
using. using
,
. C++ ( ,
) using $
:
#include <iostream>
#include <vector>
using namespace std;
using namespace org_semantics;

. , ,
: ,
. , $
, $
. , ,
, using
( $
), . $
, , $
,
.
using $
, , $
, using.
:
void aFunc() {
using namespace std;
//...
int vector = 12;
vector<int> a;
std::vector<int> b;
//...

// using
// ...
// ! std::vector
// OK,

92

23
}

using (using declara$


tion), $
:
void aFunc() {
using std::vector;
//...
int vector = 12;
vector<int> a;
//...

// using
// ! vector
// OK

Using$

using, $
, :
void aFunc() {
using std::cout;
using std::endl;
using org_semantics::String;
String a, b, c;
//...
cout << a << b << c << endl;
// ..
}


:
namespace S = org_semantics;

S
org_semantics. using, $
. (
, S, , $
, org_semantics)

:
namespace {
int anInt = 12;
int aFunc() { return anInt; }
}

93

,
__compiler_generated_name__ ( )
:
namespace __compiler_generated_name__ {
int anInt = 12;
int aFunc() { return anInt; }
}
using namespace __compiler_generated_name__;

$
. $
anInt aFunc ,

(. . ),
, , .

24 | 
$ .
. $
. ,
. . ,
( ; . 25 , 8
26 ) , $
.
, , $

,
.
:
class B {
public:
//...
void f( double );
};
class D : public B {
void f( int );
};
//...
D d;
d.f( 12.3 ); //

?
1: . $
D, D.
D::f.

95

2: $
. , D::f, $
. $
12.3 double int. ( , , , $
, .)
3: . , $
D::f .
$
, ,
, $
.
. , Java, .
, :
class E : public D {
int f;
};
//...
E e;
e.f( 12 ); // !

,
f , $.
, , ,
. $
E::f f_ m_f,
f.

25 | ,


C++ (. 23 ).
, using $
.
, $
. , (Argument
dependent lookup, ADL). C++, ADL $
, $
, .
, ADL, . , $
, $
, .
:
namespace org_semantics {
class X { ... };
void f( const X & );
void g( X * );
X operator +( const X &, const X & );
class String { ... };
std::ostream operator <<( std::ostream &, const String & );
}
//...
int g( org_semantics::X * );
void aFunc() {
org_semantics::X a;
f( a );
// org_semantics::f

g( &a );
a = a + a;

97

// ! ...
// org_semantics::operator +

org_semantics::f, $
f $
. a org_se
mantics, .
, , ADL, $
. g org_se
mantics::X . , , $
, g.
org_semantics::X *,
g , . $
, , $
, , ,
org_semantics::g, ::g. ,
, .
, , g
$ , ::g
org_semantics::g,
(. 21 ).
ADL ,
.
ADL $
, $
operator + aFunc. a+a
operator +(a,a), ADL operator+ $
org_semantics (. 26
).
C++
ADL, . $
<iostream>:
org_semantics::String name( "Qwan" ); // QWAN QualityWithoutAName,
std::cout << "Hello, " << name;
// ,

( ) operator<<, $
, $ std::ba
sic_ostream, $ $
operator<< org_semantics. $
, ADL
.

26 |
, $ $
$. . ,
. , $
$:
class X {
public:
X operator %( const X & ) const; //
X memFunc1( const X & );
void memFunc2();
//...
};

$
, :
X
a
a
a

a, b, c;
= b % c;
//  %
= b.operator %( c ); // 
= b.memFunc1( c );
// 

(.
24 8) b.operator %(c) $
, memFunc1.
:
X operator %( const X &, int ); // 
//...
void X::memFunc2() {
*this % 12;
//  %
operator %( *this, 12 );
// !
}

99

,
(. 25 , 8
). , operator % $
. ,
. $

$. ,
. ( this
$!)

ADL, , $
,
( ) , $
. ADL $
, . $
, . $
(. 21
). ADL, $
.

27 |
,
,
. , $
; :
class Shape {
public:
virtual ~Shape();
virtual void draw() const = 0;
//...
};
//...
Shape *s = getSomeShape(); // ...
s>draw();
// ... !

, , , $
, Shape , , . $
, , .
.
. , , ,
:
class Rollable {
public:
virtual ~Rollable();
virtual void roll() = 0;
};

, Rollable (, ), 8
, ,

101

Java$.
, , $
, ,
Rollable. : , $
Rollable, ; :
class Circle : public Shape, public Rollable { //
//...
void draw() const;
void roll();
//...
};
class Square : public Shape {
//
//...
void draw() const;
//...
};

, , :
class Wheel : public Rollable { ... };

, $
( roll()) , $
Rollable ,
Shape .
vector<Rollable *> rollingStock;
//...
for( vector<Rollable *>::iterator i( rollingstock.begin() );
i != rollingStock.end(); ++i )
(*i)>roll();

, , $
, .
. C++ $
dynamic_cast ( $
) (. 9 8
).
Shape *s = getSomeShape();
Rollable *roller = dynamic_cast<Rollable *>(s);

dynamic_cast (cross8
cast), $
, (. 27.1).
s Square, dynamic_cast (
), , Shape, s, Rol

102

27

. 27.1. : ?

lable. s Circle Shape, $


Rollable, , , $
.
Shape *s = getSomeShape();
if( Rollable *roller = dynamic_cast<Rollable *>(s) )
roller>roll();

,
.
. ,
$
.

28 |
C++ . $
. $
.
class Shape { ... };
class Subject { ... };
class ObservedBlob : public Shape, public Subject { ... };

ObservedBlob Shape,
Subject, ( ) $
ObservedBlob .
ObservedBlob *ob = new ObservedBlob;
Shape *s = ob;
//
Subject *subj = ob;
//

, ObservedBlob
.
if( ob == s ) ...
if( subj == ob ) ...

, , $
ob, s subj, . $
ObservedBlob,
(. 28.1).
s subj Shape Subject
, ,
ob. Shape
, ObservedBlob, , ob s $
.

104

28

. 28.1.
.

ob, s subj Ob


servedBlob, , ob s,
subj. ( s subj, $
.) $
$
. ,
ob == subj

() :
ob ? (ob+delta == subj) : (subj == 0)

delta Subject ObservedBlob. $


, ob subj , ; ob $
, Subject,
subj.
:
( )
, .
void :
void *v = subj;
if( ob == v )

// !

subj
$ void *,
, . $
.

29 |

, .
, $
, ( ) $
. , .
,
. :
, . 8
, . ,
. ,
.
? , . (, ,
.)
. $,
. $, . ,
, , ? $
, .
$ (
) , $
$
.
, , :
, .
, $
. $
.

106

29

,
. ,
, ,
.
,
: ,
, $
.
$, ,
C++ . ,
, $

,
. 8
(Prototype).
, 8 ,
. , (meal).
class Meal {
public:
virtual ~Meal();
virtual void eat() = 0;
virtual Meal *clone() const = 0;
//...
};

Meal $
clone. clone $
(. 30 ), $
, $
$
. , Meal (
, ),
.
class Spaghetti : public Meal {
public:
Spaghetti( const Spaghetti & );
//
void eat();
Spaghetti *clone() const
{ return new Spaghetti( *this ); } //
//...
};

107

( clone $
,
31 .)

Meal, Meal. $
, $
, , $ $
Meal .
const Meal *m = thatGuysMeal();
Meal *myMeal = m>clone();

// ...
// ... !

, , $
.
.
,
Meal $
.
$
, , $
, . $
, .

30 |
$
. $
, Employee () $
. Em
ployee HRInfo ( ), . 30.1.

. 30.1. .
?

Employee HRInfo . $
Salary () Hourly ( ) Std
Info, Temp () TempInfo.
: $
. , $
,

109

. , ,
HRInfo,
Employee.
switch $
:
class Employee {
public:
enum Type { SALARY, HOURLY, TEMP };
Type type() const { return type_; }
//...
private:
Type type_;
//...
};
//...
HRInfo *genInfo( const Employee &e ) {
switch( e.type() ) {
case SALARY:
case HOURLY: return new StdInfo( e );
case TEMP:return new TempInfo( static_cast<const Temp *>(e) );
default: return 0;
// !
}
}

dynamic_cast
Employee:
HRInfo *genInfo( const Employee &e ) {
if( const Salary *s = dynamic_cast<const Salary *>(&e) )
return new StdInfo( s );
else if( const Hourly *h = dynamic_cast<const Hourly *>(&e) )
return new StdInfo( h );
else if( const Temp *t = dynamic_cast<const Temp *>(&e) )
return new TempInfo( t );
else
return 0;
// !
}

genInfo ,
Employee HRInfo

HRInfo. Employee, HRInfo
.
( ) $
; ,

110

30

.
Employee. $
, genInfo().
, ,
Employee HRInfo.
, , HRInfo $
Temp? , Temp:
class Temp : public Employee {
public:
//...
TempInfo *genInfo() const
{ return new TempInfo( *this ); }
//...
};

$ , ,
, .
:
class Employee {
public:
//...
virtual HRInfo *genInfo() const = 0; //
//...
};

(Factory Method). $
, , :
, .
Employee *e = getAnEmployee();
//...
HRInfo *info = e>genInfo();

//

, $
$ $
. $
, $
. $
( )
( ).
$

$
, . $
.

31 |
,
, , :
class Shape {
public:
//...
virtual double area() const = 0;
//...
};
class Circle : public Shape {
public:
float area() const; // !
//...
};


. B , $
B *, $
D *, D B.
( D B.)
B &,
D &.
( Shape) (. 29 8
):
class Shape {
public:
//...
virtual Shape *clone() const = 0; //
//...
};

112

31
class Circle : public Shape {
public:
Circle *clone() const;
//...
};

, $
Circle *, Shape *. , Circle
Shape. , Circle::clone $
Circle * Shape *, Circle $
Shape (. 28 ):
Shape *s1 = getACircleOrOtherShape();
Shape *s2 = s1>clone();

$
, $
:
Circle *c1 = getACircle();
Circle *c2 = c1>clone();

Circle::clone $
Shape::clone Shape *.
Circle *.
Circle *c1 = getACircle();
Circle *c2 = static_cast<Circle *>(c1>clone());

Shape, $
, $
(. 30 ):
class ShapeEditor { ... };
class Shape {
public:
//...
virtual const ShapeEditor &
getEditor() const = 0; //
//...
};
//...
class Circle;
class CircleEditor : public ShapeEditor { ... };
class Circle : public Shape {
public:
const CircleEditor &getEditor() const;
//...
};

113

, CircleEditor $
( ) Circle::getEditor.
CircleEditor,

( ) CircleEditor (
) ShapeEditor. (. 28 .)
, $
.
Shape, ShapeEditor; $
, Circle,
CircleEditor. $
( )
, :
Shape *s = getACircleOrOtherShape();
const ShapeEditor &sed = s>getEditor();
Circle *c = getACircle();
const CircleEditor &ced = c>getEditor();

32 |
(public, protected private)
$
. . $
:
class NoCopy {
public:
NoCopy( int );
//...
private:
NoCopy( const NoCopy & );
//
NoCopy &operator =( const NoCopy & ); //
};


, $
. $
$
,
:
void aFunc( NoCopy );
void anotherFunc( const NoCopy & );
NoCopy a( 12 );
NoCopy b( a ); // !
NoCopy c = 12; // !
a = b;
// !
aFunc( a ); // !
aFunc( 12 ); // !
anotherFunc( a ); // OK,
anotherFunc( 12 ); // OK

33 |

$
, $
. , ( $
) . $

.
class ABC {
public:
virtual ~ABC();
virtual void anOperation() = 0; //
//...
};


, , .
,
. $
, $

. $
( ),
.
class ABC {
public:
virtual ~ABC();
protected:

116

33
ABC();
ABC( const ABC & );
//...
};
class D : public ABC {
//...
};

, $
, $
ABC.
void func1( ABC );
void func2( ABC & );
ABC a;
// !
D d;
func1( d );

// OK
// !

func2( d );

// OK,


.
:
class ABC {
public:
virtual ~ABC() = 0;
//...
};
//...
ABC::~ABC() { ... }

, $
,
. (
, $
.)
,
.
.
class ABC {
protected:
~ABC();
public:
//...
};

117

,
, $
, $
:
void someFunc() {
ABC a;
// ...
ABC *p = new ABC; // ...
//...
delete p; // !
// ! a
}

34 |

, $
(heap). , $
, handle
(), body ().
$
, $
exit () abort
( ).
( abort),
.
$
:
class NoHeap {
public:
//...
protected:
void *operator new( size_t ) { return 0; }
void operator delete( void * ) {}
};

NoHeap
(. 36 8
):
NoHeap *nh = new NoHeap; // ! NoHeap::operator new
//...
delete nh;
// ! NoHeap::operator delete

119

operator new operator delete ( ),


$
. :
$
. NoHeap $
, .
$
NoHeap (. 37 ). $

, , $
(. 32 ).
class NoHeap {
public:
//...
protected:
void *operator new( size_t )
void operator delete( void *
private:
void *operator new[]( size_t
void operator delete[]( void
};

{ return 0; }
) {}
);
* );

, , .
:
class OnHeap {
~OnHeap();
public:
void destroy()
{ delete this; }
//...
};


OnHeap
, $
.
OnHeap oh1; // !
void aFunc() {
OnHeap oh2;
//...
// ! oh2
}

35 | new
. $
new $
.
void *operator new( size_t, void *p ) throw()
{ return p; }

new
operator new,
( operator new
operator delete, , ).
.
,
.
class SPort { ... };
//
const int comLoc = 0x00400000; //
//...
void *comAddr = reinterpret_cast<void *>(comLoc);
SPort *com1 = new (comAddr) SPort; // comLoc

new operator new. $


new , ,
: operator new $
.
operator new,
new. delete $
operator delete.
new operator new, $
.

new

121

, () .
new ,
.
delete com1;

// !

, , , $
. $
delete :
com1>~SPort(); // , delete

,
,
. $
$
.
, $
:
const int numComs = 4;
//...
SPort *comPorts = new (comAddr) SPort[numComs]; //

, :
int i = numComs;
while( i )
comPorts[i].~SPort();

$

.
, :
string *sbuf = new string[BUFSIZE]; //
// !
int size = 0;
void append( string buf[], int &size, const string &val )
{ buf[size++] = val; }
// !


, . ,
.
.
new $
. $

122

35

, $
( ).
const size_t n = sizeof(string) * BUFSIZE;
string *sbuf = static_cast<string *>(::operator new( n ));
int size = 0;


, (. 12 8
). $
$
new:
void append( string buf[], int &size, const string &val )
{ new (&buf[size++]) string( val ); } // new

, new
:
void cleanupBuf( string buf[], int size ) {
while( size )
buf[size].~string(); //
::operator delete( buf ); //
}

, .
( $
) .

36 |

operator new operator delete $


, .
operator new operator delete, .
new delete,
, ope
rator new operator delete (. 35 new).
$ operator new operator delete:
class Handle {
public:
//...
void *operator new( size_t );
void operator delete( void * );
//...
};
//...
Handle *h = new Handle; // Handle::operator new
//...
delete h;
// Handle::operator delete

Handle new $
operator new Handle. ope
rator new , operator new.
operator delete,
operator delete, operator new, .
operator new operator delete
$ (. 63 ),

124

36

. , $
this.
, this. $$
, :
class MyHandle : public Handle {
//...
};
//...
MyHandle *mh = new MyHandle; // Handle::operator new
//...
delete mh;
// Handle::operator delete

, MyHandle operator new operator de


lete, , $
Handle .
operator new operator delete $
:
class Handle {
public:
//...
virtual ~Handle();
void *operator new( size_t
void operator delete( void
//...
};
class MyHandle : public Handle {
//...
void *operator new( size_t
void operator delete( void

);
* );

);
*, size_t ); //
// 2

//...
};
//...
Handle *h = new MyHandle; // MyHandle::operator new
//...
delete h;
// MyHandle::operator delete


! $
(, , ) Handle::operator delete,
MyHandle::operator delete. , .
, opera
tor delete, . $
operator delete.
,

125

operator delete.
. $
.
, new
delete (heap), $
. new , $
operator new
. operator new operator delete $
, operator new operator de
lete , . , $
. , $
, $
.
. ,
Handle :
struct rep {
enum { max = 1000 };
static rep *free;
//
static int num_used;
//
union {
char store[sizeof(Handle)];
rep *next;
};
};
static rep mem[ rep::max ];
//
void *Handle::operator new( size_t ) {
if( rep::free ) {
// free
rep *tmp = rep::free;
// free
rep::free = rep::free>next;
return tmp;
}
else if( rep::num_used < rep::max ) //
return &mem[ rep::num_used++ ]; //
else
// ,...
throw std::bad_alloc();
// ... !
}
void Handle::operator delete( void *p ) { // free
static_cast<rep *>(p)>next = rep::free;
rep::free = static_cast<rep *>(p);
}

$
Handle ,
Handle . . , $
new delete .

37 |
C++ , $

.
T *aT = new T;
T *aryT = new T[12];
delete [] aryT;
delete aT;
aT = new T[1];
delete aT;

//
//
//
//
//
//

,
$
, .
operator new, $
. , , $
operator delete, . ,
(new[]), $
(new). $
.
op
erator new operator delete. :
void
void
void
void

*operator new( size_t )


*operator new[]( size_t
operator delete( void *
operator delete[]( void

throw( bad_alloc );
) throw( bad_alloc );
) throw();
* ) throw();

// operator new
// new
// operator delete
// delete

,
$

127

operator new operator delete (. 36


).
class Handle {
public:
//...
void *operator new( size_t );
void operator delete( void * );
//...
};

Handle .
Handle , $
:
Handle *handleSet = new Handle[MAX]; // ::operator new[]
//...
delete [] handleSet;
// ::operator delete[]

,
, ( ,
). $
, ,
:
class Handle {
public:
//...
void *operator new( size_t );
void operator delete( void * );
void *operator new[]( size_t n )
{ return ::operator new( n ); }
void operator delete[]( void *p )
{ ::operator delete( p ); }
//...
};

Handle,
$
(. 34 ).

,
, . operator new ()
, $
operator new. $
:
aT = new T; // operator new( sizeof(T) );

128

37

operator new . $
:
aT = static_cast<T *>(operator new( sizeof(T) ));

operator new :
aryT = static_cast<T *>(operator new[]( 5 * sizeof(T) ));

operator new $

, :
aryT = new T[5]; // 5 * sizeof(T) +

$
,
( , $
. .). $ ,
$
, .

, .
, $
operator new
operator
new (. 35 new).

38 |
1
. $
.
.
. $
. ( , $
, $
. , ?)
, , $
. $
?

1:
$, , $
.
, $
( ) $
. ( $

, .)
, $
,
. , ,
1


(Exception safety). . .

130

38

, $
,
(String) :
const char *a, *b;
String c, d;
//...
a = b; // ,
c = d; // ,

:
template <typename T>
void aTemplateContext() {
T e, f;
T *g, *h;
//...
e = f; // ? ?
g = h; // ,
//...
}

$ , $

. ,
. .

2:
, . ,
operator delete operator delete[], . $
,
$. , , $
, , $
try:
X::~X() {
try {
delete ptr1_;
delete ptr2_;
}
catch( ... ) {}
}

,
( ) $
operator delete , ptr1_ ptr2_.
:

131

X::~X() {
delete ptr1_;
delete ptr2_;
}

3:

,
,
. $
, , $
STL. $
, . $
. (.
13 .)

39 | 1

, , $
.
throw catch,

, $
. ( )
.
, String 12 8
:
String &String::operator =( const char *str ) {
if( !str ) str = "";
char *tmp = strcpy( new char[ strlen(str)+1 ], str );
delete [] s_;
s_ = tmp;
return *this;
}

, $
$
:
String &String::operator =( const char *str ) {
delete [] s_;
if( !str ) str = "";
s_ = strcpy( new char[ strlen(str)+1 ], str );
1

exception$safety. . .

133

return *this;
}


(. 38 8
), ,
, . $
,
, String .
[8]. : $
$, $
, ,
$
. ,
String::operator =. 19 8
:
void Button::setAction( const Action *newAction ) {
Action *temp = newAction>clone(); //
// ...
delete action_; // !
action_ = temp;
}

,
clone ,
. clone ,
. $
$
Button::setAction . C++ $
, :
void Button::setAction( const Action *newAction ) {
delete action_;
// !
action_ = newAction>clone();
//
// ?
}

(, ) $
( ), $
, Button $

,
try . ,

134

39


try catch:
void Button::setAction( const Action *newAction ) {
delete action_;
try {
action_ = newAction>clone();
}
catch( ... ) {
action_ = 0;
throw;
}
}

try catch ,
Button (, , $
) , clone .
, ,
Button , .
try
,
( $ ).

.

40 | RAII
++ $
. RAII $
, .
resource acquisition is initialization $
. (, ,
. ,
, .)
RAII , ++$
, , $
, , . . $
. ,
. ,

++. , $
, .
class Resource { ... };
class ResourceHandle {
public:
explicit ResourceHandle( Resource *aResource )
: r_(aResource) {} //
~ResourceHandle()
{ delete r_; }
//
Resource *get()
{ return r_; }
//
private:
ResourceHandle( const ResourceHandle & );
ResourceHandle &operator =( const ResourceHandle & );
Resource *r_;
};

136

40

ResourceHandle , $
, ,
, $
. , $
, $
. ,
RAII:
void f() {
Resource *rh = new Resource;
//...
if( iFeelLikeIt() ) //
return;
//...
g();
// ?
delete rh;
// ?
}

$
, rh.
, $
, , $
$
. RAII
, :
void f() {
ResourceHandle rh( new Resource );
//...
if( iFeelLikeIt() ) // no problem!
return;
//...
g();
// ? !
// rh !
}

RAII
, , $
. ( $
, ,
abort exit, ,
, .)
ResourceHandle *rhp =
new ResourceHandle(new Resource); // !

RAII

137

RAII C++,
,
. , $
, RAII,
. , ($
, , . .), RAII
, $
, , $
, .
:
class Trace {
public:
Trace( const char *msg ) : msg_(msg)
{ std::cout << "Entering " << msg_ << std::endl; }
Trace()
~
{ std::cout << "Leaving " << msg_ << std::endl; }
private:
std::string msg_;
};

Trace ,
. $
Trace (,
, ),
.
void f() {
Trace tracer( "f" ); // ""
ResourceHandle rh( new Resource ); //
//...
if( iFeelLikeIt() ) // !
return;
//...
g();
// ? !
// rh !
// tracer !
}

$
.
tracer rh, rh $
tracer ( ,
). , $
, $
.

138

40


, , switch $
goto. ( ,
Trace. .) $
, $
$
. , $
,
.
, ,
.

, $ $
. ( ) .
, . $
. , $
$ $

. ,
$
.

41 | new,

,
$
. . $
,
(. 39 ), $
(. 40 8
RAII). $
try try,
, .

new. new
(. 35 new). $
operator new ,
, $
:
String *title = new String( "Kicks" );

, ,
, operator new $
String. , operator new $
, , $
operator delete ( $
) . operator new,
operator delete.

140

41

,
try, $
:
String *title //
= static_cast<String *>(::operator new(sizeof(String));
try {
new( title ) String( "Kicks" ); // new
}
catch( ... ) {
::operator delete( title ); // ,
//
}

$$! ,
. , ,
, $
, String operator new operator delete (. $
36 ).
, ,
$ (, $
String ).
, , $
, , $
. operator de
lete, operator new, $
.
String *title = new String( "Kicks" ); // ,
String *title = ::new String( "Kicks" ); // new/delete

, operator new
String ,
operator delete.
operator delete operator new.
, $
, operator
new[]. ope
rator delete[].

42 |
, C++, . $
$ , ,
C++ .
++, , $
.
, $, .
.
++ . (
18 8.)
, $
, , $
. ,
, , $
,
, , , $
.
> *,
. (
, >*; . 15
.) ( , $
STL) $
, ++, , +, , +=, = [] (. 44 8
). ,
. $
, , :
template <typename T>

142

42
class CheckedPtr {
public:
explicit CheckedPtr( T *p ) : p_( p ) {}
~CheckedPtr() { delete p_; }
T *operator >() { return get(); }
T &operator *() { return *get(); }
private:
T *p_;
//
T *get() { // ,
if( !p_ )
throw NullCheckedPointer();
return p_;
}
CheckedPtr( const CheckedPtr & );
CheckedPtr &operator =( const CheckedPtr & );
};

:
CheckedPtr<Shape> s( new Circle );
s>draw();
// , (s.operator >())>draw()

operator >. >


$
: . ,
s>draw(), , s , $
operator > ( s ). $
$, (
) Shape *.
draw Shape. $
, (s.operator >())>draw(),
>, .
*,
>, , $
.
CheckedPtr<int> ip = new int;
*ip = 12;
// ip.operator *() = 12
(*s).draw(); //

C++, $
(. 40 RAII 43 8
auto_ptr ) STL,
$ . . . . Semper fidelis1.

(.) . . .

43 |

auto_ptr

RAII, auto_ptr.1
40 RAII, $
C++. $
, auto_ptr, $
. auto_ptr $
(. 42 ),
, .
using std::auto_ptr; // . 23
auto_ptr<Shape> aShape( new Circle );
aShape>draw();
//
(*aShape).draw();
//

, auto_ptr
> *, ,
. auto_ptr $
. $, . $
, $
. $, auto_ptr , $
, , ,
. $
Circle, aShape, .
auto_ptr
:
auto_ptr<Circle> aCircle( new Circle );
aShape = aCircle;
1

auto_ptr . ISO/IEC 14882:2011


unique_ptr. . . .

144

43

$ (. 50
8) auto_ptr ,
. $
auto_ptr<Circle> auto_ptr<Shape>, $
Circle * Shape * (,
Shape Circle).
auto_ptr ( $
), .
(. 13 )
. , T ,
T a;
T b( a ); // b a
a = b;
// b a

b a a ,
b a, b . auto_ptr
! aCircle aShape, , $
, . aShape $
, , , ,
aCircle. , aCircle . $
auto_ptr ; , $
auto_ptr .
,
.
. .
auto_ptr
. $, $
. $
, ,
, auto_ptr,.
,
auto_ptr. $, auto_ptr ,
. , , $
auto_ptr, operator delete,
. auto_ptr , $
(. 37 ).
vector< auto_ptr<Shape> > shapes; // ,
auto_ptr<int> ints( new int[32] ); // , ()

vector string
auto_ptr .

44 |
. C++,
:
const int MAX = 10;
short points[MAX];
short *curPoint = points+4;

(. 44.1).

. 44.1. ,

curPoint,
short $
points. , $
, . $
curPoint , $

146

44

sizeof(short) . $
void *: ,
void *, $
.
, , , $
, . C++
, :
const int ROWS = 2;
const int COLS = 3;
int table[ROWS][COLS];

// ROWS ,
// COLS int
int (*ptable)[COLS] = table; // COLS int

, . 44.2,
, , $
(. 44.3).

. 44.2.

. 44.3.

147

ptable ,
, , $
ptable. COLS
( sizeof(int)*COLS ), int.
$
. ( ), $
.
( ), , $
; .
$
, .
ptrdiff_t, $
int. $
, ,
. (. 35
new).

STL (. 4 8
42 ).
STL , $
, . , $
STL. $
STL (. 44.4).

. 44.4. .
,

$
:
int a[] = { 1, 2, 3, 4 };
std::list<int> lst(a, a+4);
std::list<int>::iterator iter = lst.begin();
++iter;

148

44

, $
. ++iter $
iter ,
.
.
:
, $
.

45 |
,
, C++
C++
.
C++
. 45.1.

. 45.1. .

150

45

,
, , $
.
template <typename T> // T
class Heap { ... };
//...
Heap<double> dHeap; // double

, , $
, , $
.
C++
. , , $
.
. , Heap<int>, $
Heap int. print( 12.3 )
print double. $
.
, Heap int, Heap<int>
, (. 46
).
1 Heap (. 47 8
), .

:
template<typename T1, typename T2, , typename TN> MyClass { };
. 46. . . .

46 |

. $,
, . $
.
template <typename T> class Heap;

, $
( Heap),
( Heap ):
template <typename T>
class Heap {
public:
void push( const T &val );
T pop();
bool empty() const { return h_.empty(); }
private:
std::vector<T> h_;
};

, $
. $
,
. $
. $

. , push pop $
push_heap pop_heap:

152

46
template <typename T>
void Heap<T>::push( const T &val ) {
h_.push_back(val);
std::push_heap( h_.begin(), h_.end() );
}
template <typename T>
T Heap<T>::pop() {
std::pop_heap( h_.begin(), h_.end() );
T tmp( h_.back() );
h_.pop_back();
return tmp;
}

,
.
$
<.
, , $
, .
, , ,
.
$
Heap :
template <>
class Heap<const char *> {
public:
void push( const char *pval );
const char *pop();
bool empty() const { return h_.empty(); }
private:
std::vector<const char *> h_;
};

, ,
, . ,
,
.
8
, ,
(. 47 ).
.

(. 45 ). Heap<const char *>
, Heap<int>. $

153

Heap (
, const char *).

Heap.
$
const char *. , push
, $
, , :
bool strLess( const char *a, const char *b )
{ return strcmp( a, b ) < 0; }
void Heap<const char *>::push( const char *pval ) {
h_.push_back(pval);
std::push_heap( h_.begin(), h_.end(), strLess );
}

template ()
Heap<const char *>::push. $
, , ,
Heap<const char *> .
,
Heap const char * Heap:
Heap<int> h1;
//
Heap<const char *> h2; //
Heap<char *> h3;
// !


. $
( Heap, , $
), ,
. $
Heap char * Heap const char *, $
.
template <>
class Heap<char *> {
public:
void push( char *pval );
char *pop();
size_t size() const;
void capitalize();
// empty() !
private:
std::vector<char *> h_;

154

46
};


. $
, Heap const char *
push const char *, const char *&.
.
Heap char *
.
size ( ) capitalize
( ), $
, empty (), ,
. $
,
(
). $
$
, ,
(. 2 ). , , $
, (
) , $
, ,
(, ,
). :
template <typename T, typename Out>
void extractHeap( Heap<T> &h, Out dest ) {
while( !h.empty() )
*dest++ = h.pop();
}

$
Heap char *, :
Heap<const char *> heap1;
//...
vector<const char *> vec1;
extractHeap( heap1, back_inserter(vec1) ); // ...

:
Heap<char *> heap2;
//...
vector<char *> vec2;
extractHeap( heap2, back_inserter(vec2) ); // !  empty()
// Heap char *

47 |

: .
C++ ( , $
). (. 58
). .
. $
, , $
, .
Heap 46 :
template <typename T> class Heap;

( ) $
, $
. 46 $
, Heap
const char * char *. Heap
: Heap ,
,
.
Heap<double *> readings;

// , T  double *

(double *) $
,
. double *
, $
. :
template <typename T>

156

47
class Heap<T *> {
public:
void push( const T *val );
T *pop();
bool empty() const { return h_.empty(); }
private:
std::vector<T *> h_;
};

$
, . ,
, $
(. 45 ).
$
. , ,
, . $
, ,
(. 20 8 STL):
template <typename T>
struct PtrCmp : public std::binary_function<T *, T *, bool> {
bool operator ()( const T *a, const T *b ) const
{ return *a < *b; }
};

$
push:
template <typename T>
void Heap<T *>::push( T *pval ) {
if( pval ) {
h_.push_back(pval);
std::push_heap( h_.begin(), h_.end(), PtrCmp<T>() );
}
}

, ,
, .
template .
,
Heap . ,
T *, T .
. Heap
() ,
. , Heap const char *
char * , $
const char * char *.

157


Heap<std::string> h1;
Heap<std::string *> h2;
Heap<int **> h3;
Heap<char *> h4;
Heap<char **> h5;
Heap<const int *> h6;
Heap<int (*)()> h7;

//
//
//
//
//
//
//

, T std::string
, T
, T
char *
, T
, T
, T

std::string
int *
char *
const int
int ()


, $
. , $
.
.
, $
:
template <typename T>
class Heap<const T *> {
//...
};
//...
Heap<const int *> h6; // , T int

, , 46 8
,
. $
( Heap $
), $
, $
.
:

, , $
. Heap $
. $
, Heap
:
template <typename T> class Heap;

, Heap $ $
,
, :
template <> class Heap<char *>;

158

47

Heap
, $
( ) :
template <typename T> class Heap<T *>;

.
template <typename T, int n> class Heap<T [n]>;

Heap
. :
Heap<float *[6]> h8; // , T float *, n 6

: $
,
T n . $
:
template <typename R, typename A1, typename A2>
class Heap<R (*)(A1,A2)>;
template <class C, typename T>
class Heap<T C::*>;

$
Heap $, $
, $ (
, ):
Heap<char *(*)(int,int)> h9;

//
//
Heap<std::string Name::*> h10; //
//


R char *, A1 A2 int

T string, C Name

48 |


, $ $
$ . .
$
, ,
. , $
, $
. ,
, , $
.
,
, $
. $
$$
. Heap (. 46 8
):
template <typename T>
class Heap {
public:
void push( const T &val );
T pop();
bool empty() const { return h_.empty(); }
private:
std::vector<T> h_;
};

160

48

Heap const char * $


, , $
$
. $$
push pop:
template <>
void Heap<const char *>::push( const char *const &pval ) {
h_.push_back(pval);
std::push_heap( h_.begin(), h_.end(), strLess );
}
template<>
const char *Heap<const char *>::pop() {
std::pop_heap( h_.begin(), h_.end(), strLess );
const char *tmp = h_.back();
h_.pop_back(); return tmp;
}

$
Heap. $
Heap<const char *>.
, $
,
. , , push
const T &. , $
push const char * const char *const &.
( .) $
, , $
Heap , push
const char *.
( $
) , , $
Heap
(. 47 ):
template <typename T>
class Heap<T *> {
//...
void push( T *pval );
//...
};

Heap , $
push push $
, Heap<const char *>

161

.
:
template <>
void Heap<const char *>::push( const char *pval ) {
h_.push_back(pval);
std::push_heap( h_.begin(), h_.end(), strLess );
}

. $, $

, $.
$,
. , $
,
,
. $
, ,
.
template void Heap<double>::push( const double & );

61 , 8
.

49 |

typename

C++
. $
, ,
, $
.
$
.
template <typename T>
class PtrList {
public:
//...
typedef T *ElemT;
void insert( ElemT );
//...
};

$
. $
$
(. 53 54
).
typedef PtrList<State> StateList;
//...
StateList::ElemT currentState = 0;

typename

163

ElemT ,
PtrList . $
PtrList State,
State *. PtrList $
. , PtrList $
, $
(. 52 8
). $
PtrList .
:
template <typename Etype>
class SCollection {
public:
//...
typedef Etype ElemT;
void insert( const Etype & );
//...
};

, SCollection
, PtrList, $
ElemT.
, ( )
, $
. , $
,
:
template <class Cont>
void fill( Cont &c, Cont::ElemT a[], int len ) { // !
for( int i = 0; i < len; ++i )
c.insert( a[i] );
}

, . Cont::
ElemT ! ,
fill $
, ElemT . $
, .
, .
, ,
. :
class MyContainer {

164

49
public:
typedef State ElemT;
//...
};
//...
MyContainer::ElemT *anElemPtr = 0;

.
MyContainer ( ), $
ElemT , MyContainer::ElemT $
. , ,
.
typedef PtrList<State> StateList;
//...
StateList::ElemT aState = 0;
PtrList<State>::ElemT anotherState = 0;


,
PtrList<State> MyContainer.
, , ElemT $
.
$,
. :
template <typename T>
void aFuncTemplate( T &arg ) {
...T::ElemT...


T::ElemT? , T $
. , T ,
T
(::). , , $
T . , $
aFuncTemplate PtrList. T::ElemT .
PtrList<State> states;
//...
aFuncTemplate( states ); // T::ElemT PtrList<State>::ElemT

aFuncTemplate ?
struct X {
enum Types { typeA, typeB, typeC } ElemT;
//...
};

typename
X anX;
//...
aFuncTemplate( anX );

165

// T::ElemT X::ElemT

T::ElemT $, . $
? ,
, , $
. $
fill.
,
, .
template <typename T>
void aFuncTemplate( T &arg ) {
...typename T::ElemT...

typename ( )
, .

. , ,
ElemT, T. , T . $

typename A::B::C::D::E

, ( ) E $
.
, aFuncTemplate , $
, $
.
struct Z {
//
};
Z aZ;
//...
aFuncTemplate( aZ );
aFuncTemplate( anX );
aFuncTemplate( states );

ElemT...

// ! Z::ElemT
// ! X::ElemT
// OK. ElemT

fill,
:
template <class
void fill( Cont
for( int i =
c.insert(
}

Cont>
&c, typename Cont::ElemT a[], int len ) { // OK
0; i < len; ++i )
a[i] );

50 | 
, .
.
, :
template <typename T>
class SList {
public:
SList() : head_(0) {}
//...
void push_front( const T &val );
void pop_front();
T front() const;
void reverse();
bool empty() const;
private:
struct Node {
Node *next_;
T el_;
};
Node *head_; // >
};

$ ,
,
:
template <typename T>
bool SList<T>::empty() const
{ return head_ == 0; }

$
, $

167

. ( $
Node, Node, SList, $
.) $
, :
template <typename T>
class SList {
public:
//...
private:
struct Node;
//
Node *head_;
// >
//...
};
template <typename T> //
struct SList<T>::Node {
Node *next_;
T el_;
};

empty Node . (
) $. (, $
, , C++ $
, .
new opera
tor new, , const_iterator $
, ,
.)
$ , :
template <typename T>
class SList {
public:
//...
template <typename In> SList( In begin, In end );
//...
};

SList, , $
$, In .
,
SList, . $
$ :
template <typename T> // SList
template <typename In>
//
SList<T>::SList( In begin, In end ) : head_( 0 ) {

168

50
while( begin != end )
push_front( *begin++ );
reverse();
}

,
,
(. 57 ):
float rds[] = { ... };
const int size = sizeof(rds)/sizeof(rds[0]);
std::vector<double> rds2( rds, rds+size );
//...
SList<float> data( rds, rds+size );
// In float *
SList<double> data2( rds2.begin(), rds2.end() ); // In
// vector<double>::iterator

STL,
, $
. $ $
$, $
:
template <typename T>
class SList {
public:
//...
template <typename S>
SList( const SList<S> &that );
template <typename S>
SList &operator =( const SList<S> &rhs );
//...
};

, $
:
SList<double> data3( data ); // T double, S float
data = data3;
// T float, S double

$
.
, $
$. T S $
, $, $
.

169

, $
:
template <typename T>
class SList {
public:
//...
SList( const SList
SList &operator =(
template <typename
template <typename
SList &operator
//...
};
//...
SList<float> data4( data
data3 = data2;
data3 = data4;

&that );
//
const SList &rhs ); //
S> SList( const SList<S> &that );
S>
=( const SList<S> &rhs );

); //
//
//

$ ($$
, $
$
). ,
:
template <typename T>
class SList {
public:
//...
template <typename Comp> void sort( Comp comp );
//...
};

$ sort $
$, $
(. 20 88
STL).
data.sort( std::less<float>() );
//
data.sort( std::greater<float>() ); //

sort
$ less () greater ().

51 |

template

49
, $
, $
.
.
STL. $
STL, . $
, , , .
,
STL. $
:
template <class T>
class AnAlloc {
public:
//...
template <class Other>
class rebind {
public:
typedef AnAlloc<Other> other;
};
//...
};

template

171

AnAlloc rebind ( $
), .
STL , $
, ,
. :
typedef AnAlloc<int> AI;

//
//
typedef AI::rebind<double>::other AD; //
typedef AnAlloc<double> AD;
//


int
double
!

,

, .
typedef SomeAlloc::rebind<Node>::other NodeAlloc;

SomeAlloc STL ,
rebind. $
: , , ,
, $
Node!.
,

. SList 50 8, $
(A),
( T). , SList $
:
template < typename T, class A = std::allocator<T> >
class SList {
//...
struct Node {
//...
};
typedef A::rebind<Node>::other NodeAlloc; // !
//...
};

,
T T
. , T. $
. ,
, T,
Node. rebind
.

172

51

, ,
A, ,
. ,
rebind , ,
, . $
. ,
other, $ , rebind
, , ! $
$ . typedef :
typedef typename A::template rebind<Node>::other NodeAlloc;

template , rebind
, typename ,
. , ?

52 |


,
(. 46 8
47 ).
$
, $
, $
. :
template <typename T>
struct IsInt
// T int...
{ enum { result = false }; };
template <>
struct IsInt<int>
// int!
{ enum { result = true }; };

, , $
(
). ,
. . ,
, .
, ,
,
: int, int. $
C++ , $
.

174

52

, ( $
), int:
template <typename X>
void aFunc( X &arg ) {
//...
...IsInt<X>::result...
//...
}


. $
, , $ int,
. , , ,
, ,
, :
struct Yes {};
struct No {};

// , true
// , false

template <typename T>


struct IsPtr
// T ...
{ enum { result = false }; typedef No Result; };
template <typename T>
struct IsPtr<T *>
// ,
{ enum { result = true }; typedef Yes Result; };
template <typename T>
struct IsPtr<T *const>
// ,
{ enum { result = true }; typedef Yes Result; };
template <typename T>
struct IsPtr<T *volatile> // ,
{ enum { result = true }; typedef Yes Result; };
template <typename T>
struct IsPtr<T *const volatile> // .
{ enum { result = true }; typedef Yes Result; };

IsPtr , IsInt.
, $
$ $
. , IsPtr
, IsInt. $
. ( $
59 SFINAE.)

,
:

175

template <typename T>


class Stack {
public:
~Stack();
void push( const T &val );
T &top();
void pop();
bool empty() const;
private:
//...
typedef std::deque<T> C;
typedef typename C::iterator I;
C s_;
};

$ $
deque. $
, stack. $

deque.
template <typename T>
void Stack<T>::push( const T &val )
{ s_.push_back( val ); }

Stack.
Stack deque, , , $
, deque.
, ,
, . $
deque.
Stack, ! (
56 .) $
deque ,
, .

() Stack (. 47
). , , ,
Stack. $
( ) $
: , Stack,
, .
.
template <typename T>
class Stack {

176

52
public:
~Stack()
{ cleanup( typename IsPtr<T>::Result() ); }
//...
private:
void cleanup( Yes ) {
for( I i( s_.begin() ); i != s_.end(); ++i )
delete *i;
}
void cleanup( No )
{}
typedef std::deque<T> C;
typedef typename C::iterator I;
C s_;
};

$ cleanup (),
Yes (),
No (). Yes ;
No . : T ?. $
IsPtr T, $
Result () (. 49 8
typename),
Yes No, cleanup. $
cleanup (. 61 8
, ).
Stack<Shape *> shapes;
//
Stack<std::string> names; //


. ,
, , ,
, :
template <typename T>
struct IsArray {
// T ...
enum { result = false };
typedef No Result;
};
template <typename E, int b>
struct IsArray<E [b]> { // ... !
enum { result = true };
typedef Yes Result;
enum { bound = b }; //
typedef E Etype;
//
};

177

, $
$, , ,
, :
template <typename T>
struct IsPCM {
// T 
enum { result = false };
typedef No Result;
};
template <class C, typename T>
struct IsPCM<T C::*> {
// ... !
enum { result = true };
typedef Yes Result;
typedef C ClassType; //
typedef T MemberType; //
};


,
(. 54 ) .

53 |
?
template <typename T>
class Seq {
//...
};

. Seq<std::string> $
std::string, ? . ($
)
const T, T * T. ($ $

void *!) $
, . $
, $
.
template <class Container>
Elem process( Container &c, int size ) {
Temp temp = Elem();
for( int i = 0; i < size; ++i )
temp += c[i];
return temp;
}

process
(Elem) (Container), ,

(Temp). , $
process .

179

$
.
. ,
, ,
. . ( , .) $
,
.
template <class T>
class Seq {
public:
typedef T Elem; //
typedef T Temp; //
size_t size() const;
//...
};

:
typedef Seq<std::string> Strings;
//...
Strings::Elem aString;

$
. , $
, :
vector<int> aVec;
//...
for( vector<int>::iterator i( aVec.begin() );
i != aVec.end(); ++i )
//...

, int * (
), vector<int>
. vector<int>
(, ). $
, $
vector<int>.
$
, .
template <class Container>
typename Container::Elem process( Container &c, int size ) {
typename Container::Temp temp
= typename Container::Elem();
for( int i = 0; i < size; ++i )
temp += c[i];

180

53
return temp;
}

process Container
, Container
Elem Temp. ( typename
, , $ $
. . 49
.)
Strings strings;
aString = process( strings, strings.size() ); // OK

process Seq
, .
template <typename T>
class ReadonlySeq {
public:
typedef const T Elem;
typedef T Temp;
//...
};

process ReadonlySeq,
.

54 |
.
, $
. 53 ,
, ,
:
Strings strings;
aString = process( strings, strings.size() ); // OK
std::vector<std::string> strings2;
aString = process( strings2, strings2.size() ); // !
extern double readings[RSIZ];
double r = process( readings, RSIZ );

// !

process Seq,
vector, vector $
, process.
process ReadonlySeq,
.
process ,
, , $
.
(traits classes).
.
, ,
.
template <typename Cont>
struct ContainerTraits;

182

54

$
,
. .
$ .
ContainerTraits ,
Seq ReadonlySeq.
template <typename Cont>
struct ContainerTraits {
typedef typename Cont::Elem Elem;
typedef typename Cont::Temp Temp;
typedef typename Cont::Ptr Ptr;
};

.
Elem
, ,
.
typedef Seq<int> Cont;
Cont::Elem e1;
ContainerTraits<Cont>::Elem e2; // , e1


:
template <typename Container>
typename ContainerTraits<Container>::Elem
process( Container &c, int size ) {
typename ContainerTraits<Container>::Temp temp
= typename ContainerTraits<Container>::Elem();
for( int i = 0; i < size; ++i )
temp += c[i]; return temp;
}

,
process! , ,
typename Container::Elem.
: Elem Container. ,
. typename Container
Traits<Container>::Elem. : Container
Traits, ,
Elem. , . $
, , $
.
, $
$

183

.
, , ,
.
, , .
(, , $
.)
, .
,
$
, :
class ForeignContainer {
// ...
};
//...
template <>
struct ContainerTraits<ForeignContainer> {
typedef int Elem;
typedef Elem Temp;
typedef Elem *Ptr;
};

ContainerTraits,
process ForeignContainer , ,
. $
process ForeignContainer , $
:
ForeignContainer::Elem x;

// , !

ContainerTraits<ForeignContainer>::Elem y; // OK,

, $
, , $
.
.

, $
, , ,
. , $
, , ,
. , (
) ,
.
template <>
struct ContainerTraits<const char *> {

184

54
typedef const char Elem;
typedef char Temp;
typedef const char *Ptr;
};

const
char *, process .
const char *name = "Arsene Lupin";
const char *r = process( name, strlen(name) );

,
int *, const double * . . $
,
.
:
template <typename T>
struct ContainerTraits<T *> {
typedef T Elem;
typedef T Temp;
typedef T *Ptr;
};

ContainerTraits , int *
const float *(*const *)(int), $
, $
ContainerTraits.
extern double readings[RSIZ];
double r = process( readings, RSIZ ); // !

. , $
$
.
, $
. $
. const char *, ,
ContainerTraits<const char *>::Temp char, const char.
.
template <typename T>
struct ContainerTraits<const T *> {
typedef const T Elem;
typedef T Temp;
// : Elem
typedef const T *Ptr;
};

185

$
, $
, .
$
$
. , STL $
(. 4 ),
, ,
ContainerTraits, . $
process vector $
.
template <class T>
struct ContainerTraits< std::vector<T> > {
typedef typename std::vector<T>::value_type Elem;
typedef typename
std::iterator_traits<typename
std::vector<T>::iterator>
::value_type Temp;
typedef typename
std::iterator_traits<typename
std::vector<T>::iterator>
::pointer Ptr;
};

, $
, ,
, $
vector.
std::vector<std::string> strings2;
aString = process( strings2, strings2.size() ); // !

55 | 
Stack, 52 8
. $
deque. $
,
. $
Stack
, .
template <typename T, class Cont>
class Stack;

(
) ,
: List, Vector, Deque , $
, . , ,
.
,
: . $
,
. $
,
(. 56 ).
, . $
, vector<int>, $
vector< int, std::allocator<int> >.
, List :
template <typename> class List;

187

, List
.
: $
. :

. , $
,
,
.
template <typename T, class Cont>
class Stack {
public:
~Stack();
void push( const T & );
//...
private:
Cont s_;
};

Stack
,
.
Stack<int, List<int> > aStack1;
// OK
Stack<double, List<int> > aStack2;
// ,
Stack<std::string, Deque<char *> > aStack3; // !

aStack2 aStack3 .
, $
( aStack3 $ $
string char *) ( aStack2 $ $
double int). , $
Stack $
. ,
:
template <typename T, class Cont = Deque<T> >
class Stack {
//...
};

, Stack Deque
.
Stack<int> aStack1;
Stack<double> aStack2;

// Deque<int>
// Deque<double>

188

55

, $
stack, queue priority_queue.
std::stack<int> stds; // deque< int, allocator<int> >

$
Stack $
, ($
) Stack.
. $ $
$
, .
Stack<int, List<int> > aStack3;
Stack<int, List<unsigned> > aStack4; // !

,
. , $
. $
8 (template template parameters).
template <typename T, template <typename> class Cont>
class Stack;

Stack $
, , . $
, T, . . ,
Cont $ . $
. , Cont
, :
template <typename T, template <typename ElementType> class Cont>
class Stack;

(ElementType ( )) $
$
. ,
, . , $
,
Stack :
template <typename, template <typename> class>
class Stack;

, ,
, , C++ .

189

Stack $
$.
Stack:
template <typename T, template <typename> class Cont> class Stack {
//...
private:
Cont<T> s_;
};

$
Stack, , Stack.
$
, $
.
Stack<int,List> aStack1;
Stack<std::string,Deque> aStack2;

$
$ :
template <typename T, template <typename> class Cont = Deque>
class Stack {
//...
};
//...
Stack<int> aStack1;
// :
// Cont Deque
Stack<std::string,List> aStack2; // Cont List


, $
.
$ ,
. $
:
template <class Cont> class Wrapper1;

Wrapper1 (1)
. ( Cont Wrapper1 $
typename class,
, class struct,
. . ty
pename class . . 63 8
.)
, Wrapper1<List<int>>, List<int> $

190

55

, ,
.
Wrapper1< List<int> > w1;
// , List<int> 
Wrapper1< std::list<int> > w2; // , list<int> 
Wrapper1<List> w3;
// ! List


:
template <template <typename> class Cont> class Wrapper2;

Wrapper2 ,
. ,
.
Wrapper2<List> w4;
Wrapper2< List<int> > w5;
Wrapper2<std::list> w6;

//
//
//
//

,
!
!

List
List<int>
std::list


, :
template <template <typename Element,
class Allocator> class Cont>
class Wrapper3;

, :
template <template <typename,typename> class Cont>
class Wrapper3;

, $
:
Wrapper3<std::list> w7;
// ...
Wrapper3< std::list<int> > w8; // ! list<int> 
Wrapper3<List> w9;
// ! List

(, ) $
,
w7 . ,
STL, , .

56 |
52
, , $
, $
.
template <typename T> class Stack;

, .
, , $
. , $
, $
. , ,
. ,
,
, NTCTS (null
terminated array of characters , $
null):
Stack<const char *> names;

// !

, Stack $
, , , $
delete, ,
delete:
operator delete[] (. 37 ).
Stack:
template <typename T>
class Stack {
public:

192

56
~Stack() {
for( I i( s_.begin() ); i != s_.end(); ++i )
doDeletionPolicy( *i );
}
//...
private:
typedef std::deque<T> C;
typedef typename C::iterator I;
C s_;
};

$
. doDele
tionPolicy ( ) $$
.
Stack $ (. 55 8
8 ).
template <typename T, template <typename> class DeletionPolicy>
class Stack {
public:
~Stack() {
for( I i( s_.begin() ); i != s_.end(); ++i )
DeletionPolicy<T>::doDelete( *i ); //
}
//...
private:
typedef std::deque<T> C;
typedef typename C::iterator I;
C s_;
};

Stack,
, Stack ,
Stack.
$ doDelete,
Stack.
. $
:
template <typename T>
struct PtrDeletePolicy {
static void doDelete( T ptr )
{ delete ptr; }
};

193

, $
. , ,
:
template <typename T>
struct PtrDeletePolicy {
void operator ()( T ptr )
{ delete ptr; }
};

Stack
DeletionPolicy<T>()(*i);

, ,
$
.
$
:
template <typename T>
struct ArrayDeletePolicy {
static void doDelete( T ptr )
{ delete [] ptr; }
};
template <typename T>
struct NoDeletePolicy {
static void doDelete( const T & )
{}
};

Stack
:
Stack<int, NoDeletePolicy> s1;
// int
Stack<std::string *, PtrDeletePolicy> s2; // string *
Stack<const char *, ArrayDeletePolicy> s3; // delete []
Stack<const char *, NoDeletePolicy> s4;
// !
Stack<int, PtrDeletePolicy> s5; // ! int!

, $
:
template <typename T,
template <typename> class DeletionPolicy = NoDeletePolicy>
class Stack;
//...
Stack<int> s6;
//
Stack<const char *> s7;
//
Stack<const char *, ArrayDeletePolicy> s8; // delete []

194

56

$
. , 55 8
$
Stack. :
template <typename T,
template <typename> class DeletionPolicy = NoDeletePolicy
template <typename> class Cont = Deque>
class Stack;

Stack :
Stack<double *, ArrayDeletePolicy, Vector> dailyReadings;

.
Stack<double> moreReadings;

// , Deque

$
. $
.

57 |

. , $
Heap, 46 8
, , $
:
Heap<int> aHeap;
Heap<const char *> anotherHeap;

. $
, , $
:
template <typename R, typename E>
R cast( const E &expr ) {
// ... ...
return R( expr );
// ... .
}

, $
, :
int a = cast<int,double>(12.3);

$
( ) .
, 8
. !

(. 45 ). $

196

57

,
.
template <typename T>
T min( const T &a, const T &b )
{ return a < b ? a : b; }

min ,
, $
:
int a = min( 12, 13 );
//
double d = min( '\b', '\a' ); //
char c = min( 12.3, 4 );
//
//

T int
T char
! T
double, int

$
$
. $
:
d = min<double>( 12.3, 4 ); // OK, T double

cast, $
:
int a = cast( 12.3 );

// ! E double, R?

,
,
. $
, :
int a = cast<int>( 12.3 ); // E double, R int ( )

,
, $
.
, $
.
, , $
, .
$
cast : , static_cast,
dynamic_cast, const_cast reinterpret_cast $
?. , ,
, ( $

197

new + ). , , $
,
cast. (. 9 .)
, $
. $
, ,
, $
. , ,
:
template <int n, typename T>
void repeat( const T &msg ) {
for( int i = 0; i < n; ++i )
std::cout << msg << std::flush;
}

int
.
$
:
repeat<12>( 42 );
// n 12, T int
repeat<MAXINT>( '\a' ); // n , T char

cast, min, repeat $


.

:
template <int bound, typename T>
void zeroOut( T (&ary)[bound] ) {
for( int i = 0; i < bound; ++i )
ary[i] = T();
}
//...
const int hrsinweek = 7 * 24;
float readings[hrsinweek];
zeroOut( readings );
// bound == 168, T float

zeroOut , $
$
.
,
. $
$
. , $

198

57

$ (. 20 8
STL):
template <typename A1, typename A2, typename R>
class PFun2 : public std::binary_function<A1,A2,R> {
public:
explicit PFun2( R (*fp)(A1,A2) ) : fp_( fp ) {}
R operator()( A1 a1, A2 a2 ) const
{ return fp_( a1, a2 );}
private:
R (*fp_)(A1,A2);
};

( pointer_to_binary_func
tion ( ). $
. .) $
:
bool isGreater( int, int );
std::sort(b, e, PFun2<int,int,bool>(isGreater)); //


(helper function), $

:
template <typename R, typename A1, typename A2>
inline PFun2<A1,A2,R> makePFun( R (*pf)(A1,A2) )
{ return PFun2<A1,A2,R>(pf); }
//...
std::sort(b, e, makePFun(isGreater));
// ...

$
,
.
, ptr_fun, make_pair,
mem_fun, back_inserter , , $

.

58 |
$
. ,
.
$
$
. $
$
( ) (
).
, $ $
,
, ($
, T const T const T T), (, T T &)
(, T[42] T *).
, $
, .
, . , $
:
template <typename T>
void g( T a, T b ) { ... }
// g
void g( char a, char b ) { ... } // g
//...
g( 12.3, 45.6 );
// g
g( 12.3, 45 );
// g!

double
g double

200

58

char (, ). $
g T double, $
. double int $
g, $
int double (
double int ), T double (
int). , g
double int char.

. $
C++
. ,
, , ,
.

.
. 57 8
, $

:
template <typename A1, typename A2, typename R>
class PFun2 : public std::binary_function<A1,A2,R> {
// . 57
...
};


, ,
$
:
template <typename R, typename A1, typename A2>
inline PFun2<A1,A2,R> makePFun( R (*pf)(A1,A2) )
{ return PFun2<A1,A2,R>(pf); }

, $
. , bool
isGreater(int,int), PFun2<int,int,bool>(isGreater),
makePFun(isGreater).
, $
:
template <typename A, typename R>
class PFun1 : public std::unary_function<A,R> {

201

public:
explicit PFun1( R (*fp)(A) ) : fp_( fp ) {}
R operator()( A a ) const
{ return fp_( a ); }
private:
R (*fp_)(A);
};

:
template <typename R, typename A>
inline PFun1<A,R> makePFun( R (*pf)(A) )
{ return PFun1<A,R>(pf);
}

.
, make
PFun ( , ).

.

59 | SFINAE

,
, $
.
template <typename T> void f( T );
template <typename T> void f( T * );
//...
f( 1024 ); // f

T * f $
, $
, .
f, . ,

(Substitution Failure Is Not An Error SFINAE),
(Vandevoorde) (Josuttis).
SFINAE , $
. $
$
. SFI$
NAE .
IsPtr, 52 8
. ,
, $
. $
SFINAE.
typedef char True; // sizeof(True) == 1

SFINAE

203

typedef struct { char a[2]; } False; // sizeof(False) > 1


//...
template <typename T> True isPtr( T * );
False isPtr( ... );
#define is_ptr( e ) (sizeof(isPtr(e))==sizeof(True))

is_ptr , , $
SFINAE.
e , isPtr; $
isPtr
. SFINAE ,
isPtr .

sizeof is_ptr. , isPtr
. , $
. sizeof

, . sizeof
, .
, $
. , e
.
,
,
IsPtr, $
. $
cv$ (const vola
tile), (. 58
).
, , $
,
.
$
, $
.

52
. $
,
. $
,

204

59

$
. , $
$
.
.
is_ptr
SFINAE.
$
. $
( ) .
, :
template <typename T>
struct IsClass {
template <class C> static True isClass( int C::* );
template <typename C> static False isClass( ... );
enum { r = sizeof(IsClass<T>::isClass<T>(0))
== sizeof(True) };
};

, SFINAE
IsClass $
IsClass.
(. 15
). $
( ). $
, T , isClass. T
, SFINAE $
isClass . is_ptr, $
, , $
, , , , T .
. $
, ,
iterator. (, $
, iterator.)
template <class C>
True hasIterator( typename C::iterator const * );
template <typename T>
False hasIterator( ... );
#define has_iterator( C )\
(sizeof(hasIterator<C>(0))==sizeof(True))

has_iterator IsClass, $
(. 49 8

SFINAE

205

). C
, $
. .
, (Andrei Alexand$
rescu). T1 T2, , T1
T2? , ,
:
template <typename T1, typename T2>
struct CanConvert {
static True canConvert( T2 );
static False canConvert( ... );
static T1 makeT1();
enum { r = sizeof(canConvert( makeT1() )) == sizeof(True) };
};

Heap 52 8
, $
, $
.
SFINAE , $
, :
, iterator, $
std::string?.

60 |
, $
, $
.
, , , $
:
template <typename T>
void slowSort( T a[], int len ) {
for( int i = 0; i < len; ++i )
//
for( int j = i; j < len; ++j )
if( a[j] < a[i] ) {
// ... ...
T tmp( a[j] );
// ... .
a[j] = a[i];
a[i] = tmp;
}
}

$
, <
. , String
12 :
String names[] = { "my", "dog", "has", "fleece" };
const int namesLen = sizeof(names)/sizeof(names[0]);
slowSort( names, namesLen );
// ... !

slowSort ( )
. , $
O(n2) .

207

, $
slowSort String ( ,
). String swap,
, , ,
String.
, :
template <typename T>
void slowSort( T a[], int len ) {
for( int i = 0; i < len; ++i )
//
for( int j = i; j < len; ++j )
if( a[j] < a[i] )
// ... ...
swap( a[j], a[i] );
// ... .
}

$ $ swap String, $
String , $ swap:
inline void swap( String &a, String &b )
{ a.swap( b ); }

swap? $
,
swap , $
, slowSort.
, $
slowSort , . , , $
$ $ swap String,
. $
.
<.
, , (
).
$ . , $
, $
<, ,
. 20 8
STL: State:
class State {
public:
//...
int population() const;
float aveTempF() const;
//...
};

208

60

, 20 8 STL,
$, $
<. ,
:
template <typename T, typename Comp>
void slowSort( T a[], int len, Comp less ) {
for( int i = 0; i < len; ++i )
//
for( int j = i; j < len; ++j )
if( less( a[j], a[i] ) )
// ... ...
swap( a[j], a[i] );
// ... .
}
//...
State states[50];
//...
slowSort( states, 50, PopComp() );

slowSort <
, , slowSort,
,
.
, , $
. slowSort $

, $
, .
, , :
template <typename For, typename Comp>
void slowSort( For b, For e, Comp less ) {
for( For i( b ); i != e; ++i )
//
for( For j( i ); j != e ; ++j )
if( less( *j, *i ) )
// ... ...
std::swap( *j, *i );
// ... .
}
template <typename For>
void slowSort( For b, For e ) {
for( For i( b ); i != e; ++i )
for( For j( i ); j != e ; ++j )
if( *j < *i )
std::swap( *j, *i );
}
//...
std::list<State> states;
//...
slowSort( states.begin(), states.end(),

//
// ... ...
// ... .

PopComp() );

209

slowSort( names, names+namesLen );

$
STL .
slowSort, $
.

. ,
,
, .
slowSort $
.
. , slowSort $
, $
, .
, () ,
, $
. , $
,
. ,
, slowSort
, , .
, . (
; . 19 .)

61 | ,

C, C++ ,
( ). $
$ : $
, .
, .
$, $
,
.

, ,
$. $
, , $
. , $

$. $
, , .
C++,
, $
. C++
, !
:
template <typename T, int n>
class Array {
public:
Array() : a_( new T[n] ) {}

211

~Array() { delete [] a_; }


Array( const Array & );
Array &operator =( const Array & );
void swap( Array &that ) { std::swap( a_, that.a_ ); }
T &operator []( int i ) { return a_[i]; }
const T &operator []( int i ) const { return a_[i]; }
bool operator ==( const Array &rhs ) const;
bool operator !=( const Array &rhs ) const
{ return !(*this==rhs); }
private:
T *a_;
};

$
: . $
, $
, $
( , ).
operator==:
template <typename T, int n>
bool Array<T,n>::operator ==( const Array &that ) const {
for( int i = 0; i < n; ++i )
if( !(a_[i] == that.a_[i]) )
return false;
return true;
}

, $
, ,
. $
. , $
Array .
Array<int,12> a, b;
//...
if( a == b ) // a.operator ==(b)
//...

Array<int,12> ==,
Array<int,12>::operator==, $
. Array<int,12>
== ( !=, operator==),
$.
Array , $
==. , , Circle
operator==:

212

61
Array<Circle,6> c, d; // !
//...
c[3].draw(); // OK

. == ,
Array<Circle,6>, operator== $
, .
if( c == d ) // !

.
Array<Circle,6>::operator==,
Circle ==.
.

.
,
:
template Array<Circle,7>; // !


Array Circle 7.
Array<Circle,7>:: operator==
. ,

62 | 1
C++ ,
. $
$
. $
.
hdr2.h,
hdr1.h, hdr3.h, hdr1.h. $
hdr2.h, hdr3.h , hdr1.h $
. $
.
C++ $
. $
,
(#include) . $
hdr1.h:
#ifndef HDR1_H
#define HDR1_H
// ...
#endif

(#include) hdr1.h $
HDR1_H , $
#ifndef ( ) $
#define $
1

(include guards) ,
, ++.

214

62

. hdr1.h
HDR1_H , #ifndef
.
, , $
( HDR1_H), $
( hdr1.h). $
,
, , $
, .
, $
$
, . , $
, #ifndef
#endif ,
,
.
:
#ifndef HDR1_H
#include "hdr1.h"
#endif

(#include) , $
,
. ,
( #ifndef
HDR1_H) #include, $
.
#include,
. $
, , $

.

63 |
C++
,
.
$
virtual $ ,
$ .
class Shape {
public:
virtual void draw() const = 0;
virtual void rotate( double degrees ) = 0;
virtual void invert() = 0;
//...
};
class Blob : public Shape {
public:
virtual void draw() const;
void rotate( double );
void invert() = 0;
//...
};

$ Blob::draw draw () $
, , .
, $
. , $
virtual
. .
class SharpBlob : public Blob {

216

63
public:
void rotate( double ); // Blob::rotate
//...
};

, virtual
, Blob::invert.
virtual $
.
.
, virtual $
, . $
, virtual $
$
. ,
$
. , $
, $
virtual $
, .
static operator
new, operator delete, (. 36 8
), .
class Handle {
public:
void *operator new( size_t );
//
static void operator delete( void * );
static void *operator new[]( size_t );
void operator delete[]( void * );
//
};

, $
. ,
C++
, .
static .
. virtual,
static, $
. $
, .
typename class $
. , $
, .

217

++ typename $,
, class .
template <typename In, typename Out>
Out copy( In begin, In end, Out result );
template <class Container>
void resize( Container &container, int newSize );

register
, ( $
) $
. ,
register. $
, , ,
, $
. $
. C++ register
.
auto , $
( ) $
. .
, , register, auto $
, .
, $
.


1. Alexandrescu, Andrei. Modern C++ Design. Addison$Wesley, 2001.1
2. Dewhurst, Stephen C. C++ Gotchas. Addison$Wesley, 2003.
3. Gamma, Erich, Richard Helm, Ralph Johnson, and John Vlissides. De8
sign Patterns. Addison$Wesley, 1995.2
4. Josuttis, Nicolai M. The C++ Standard Library. Addison$Wesley, 1999.
5. Meyers, Scott. Effective C++, Third Edition. Addison$Wesley, 2005.
6. Meyers, Scott. Effective STL. Addison$Wesley, 2001.
7. Meyers, Scott. More Effective C++. Addison$Wesley, 1996.
8. Sutter, Herb. Exceptional C++. Addison$Wesley, 2000.3
9. Sutter, Herb. More Exceptional C++. Addison$Wesley, 2002.4
10. Sutter, Herb. Exceptional C++Style. Addison$Wesley, 2005.
11. Sutter,Herb, and Andrei Alexandrescu. C++ Coding Standards. Addi$
son$Wesley, 2005.5
12. Vandevoorde, David, and Nicolai M. Josuttis. C++ Templates. Addison$
Wesley, 2003.
13. Wilson, Matthew. Imperfect C++. Addison$Wesley, 2005.
1
2

3
4
5

. C++, , 2002.
. , . , . , . $$
. , , 2001.
. C++, , 2002.
. C++, , 2005.
. , . C++, $
, 2005.

( ),

, 70
, 68
, 68
.* (, ),
, 68
>* (, , ),
, 68

A
ABC ( ), 115
abort, , 118, 136
ADL (,
), 97
auto_ptr,
, 144
, 144
, 143
, 144
, 144
, 144

$, 67
, 66

E,
exit, , 118, 136

G
get/set, , 20

H
Handle
,
119
, 59
,
124
Heap
, 151
,
154

Java C++, , 52

Circle,
,
112

O
operator delete
, 124

220
,
125
operator new
, 125
new, 122
new, 120, 123,
139
,
125

P
POD ( ), 53

Q
QWAN (Quality Without A Name
), 97

R
RAII (
), 135138
RTTI (
)

, 46
, 101
, 46
, 108

S
SFINAE (
), 205

hasIterator, 204
is_ptr, 202

CanConvert, 205
IsClass, 204
Shape
,
112

$, 67
, 66


STL ( ),
29 31


ABC, 117
Action, 79
Func, 75
Rollable, 100
, 19
, 20
, , 17, 205
, 32
. ,
, 93
, , 150
, 145
, 37, 148

process_2d, 37
set_2d, 34


,
, 117
, 24
, 117
, 88
$, , 88
, 88
, 150
SFINAE, 203


, 173
, 150
, 150
, 155, 177
, 159
, 154, 177
, ,
59

221

, , 205

, , 60
, , 54

, 107
, 76
, , 52
, , 170
, 198, 200
, , 62
, 180
, 198
, 68,
104, 112
, /

const, 45
volatile, 45
,
, 128
(exit), 118, 136
, 37
, 56, 57


aFunc, , 119
NoCopy, , 114
NoHeap, , 119
OnHeap, , 119

handle/body, 118
RAII, 138
, 131
, 106
, 57
, 114

, 144
$, 73
STL, 83
,
119

, 138
new_handler, 63

, 133

, 35

, 60
RTTI,
101

dynamic_cast , 47

, 117

, 59

, 42
, 59
, 143

, 133
, , 150
, , 165
, 55
, 55

,
, 93
,
, 137

,
, 135
, , 205
using, 91

,
, 214, 217
, 102

, 95, 114, 117


, 214

222
, 55
, 55
, 55
, 57
, 75, 100
Action, 79
Func, 75
Rollable, 100

aTemplateContext, ,
130
Button::setAction, $, 133
f, , 137
ResourceHandle, , 135
String::operator =, $, 132
Trace, , 137
X::X, $, 130
, 140

, /
const, 45
volatile, 45

ABC, 117
Action, 79
App, 87
B, 69, 84, 94
Blob, 215
Button, 77, 79
C, 65
Capability, 100
Circle
, 101
,
112
$, 67
, 66
CircleEditor, 112
ContainerTraits<const char *>, 183
ContainerTraits<ForeignContainer>,
183
D, 69, 85, 94
E, 95
Employee, 110
Fib, 73


ForeignContainer, 183
Func, 75
Handle
RAII, 135
swap, 59
,
216
,
118
, 127
Heap<char *>, 154
Heap<const char *>, 152
IsWarm, 83
Meal, 106
MyApp, 88
MyContainer, 163
MyHandle, 124
NMFunc, 75
NoCopy, 114
NoHeap, 119
ObservedBlob, 103
OnHeap, 119
PlayMusic, 79
PopLess, 82
rep, 125
ResourceHandle, 135
Rollable, 100
S, 53
Shape
, 100
,
112
,
215
, 103
$, 67
, 66
ShapeEditor, 112
SharpBlob, 215
Spaghetti, 106
Square, 101
State, 81, 207
String, 55
Subject, 103
T, 54
Temp, 110
Trace, 137

223


Wheel, 101
X, 51, 98
, 101
, 185
$, 167
SList<T>::Node, 167
, 107
, 17, 173

auto, 217
register, 217
virtual, 217
, 167
, 112
, , 78
, , 78
, 81
PopLess, , 82
popLess, , 81
PtrCmp, , 156
strLess, , 153
$ STL ,
83

, 54
, 52
,
113
, , 66

, 54
, 54
, 104
, , 52

,
, 40
$
, 49
, 50
, 49

, 51
, 51

, 107
, 122

, 117
, 140
, 140
, 140
new, 122
, , 24
, , 66
, 66

$, 66, 68
$, 66
$, 167
,
, 135
, 39

, 39
, 53
, 60
, 60
, $

Handle::operator =, 60
Handle::swap, 59
, ( )

, 70
, 68
, 68
, , 119

, 50
, 83
,
36

cast, 195
makePFun, 198, 200
minimum, 196
repeat, 197
zeroOut, 197


hasIterator, 204

224
is_ptr, 202

, 36
, 122
, 35
, 128
/
, 128
, 207
, 72
auto_ptr, 144
, 41

, 146

, 70
,
37
, 104

, 131
, 130
, 140
, 140
, 134
new, 140
, 134
, 130

, 131
, 134
, ,
78, 88

Java$, 52
, 77
, 12
, 23, 30, 209
, 107
, 171
,
, 172
$,
, 62



(SFINAE), 205
, 45
, 46

, 46
, 44

, 181, 185
, 62, 77
Action, , 79
begForgiveness, , 63
, 78
,
, 78
$ , 80
, 77
, 78
, 63

typedef, 71
, 20

, 188
, 27
, 201
, 209

body, 118
, 32
. ,
, 107
, 102
, 49
, 48, 51
$
$, 48, 76
, 52
, 107
, 53
, 114
, 122
, 114
, 49
, 24

225


, , 119
, 104
.
, 21
.
, 185

, 110
, 54
RAII, 138
$, 73
STL
, 83
, 83
, 83
, 83
, 77, 80

$, 76

Action, 79
Fib, 73
Func, 75
IsWarm, 83
NMFunc, 75
PlayMusic, 79
PopLess, 82
, 76

MFunc, 76
PFun1, 200
PFun2, 198, 200
PtrCmp, 156
, 61
using, 92
operator new operator delete,
124

, 36

* (), , 142, 144


>, , 142, 144
const_cast, 45
dynamic_cast, 47
new
, 140
, 140

, 140
operator new, 120, 123,
139
reinterpret_cast, 46
static_cast, 47
$,
$, 99

, , 72
, , 72

const_cast, 45
dynamic_cast, 47
reinterpret_cast, 46
static_cast, 47

const, /, 45
volatile, /, 45
, , 47

, 47
, 47
, 46

, 47
, 44
, 101
, 44
, 44
, 49

, , 119
,
125
, , 150
$ , 190

, 28
, 27
, 28
, 28
, 110, 113

, 88
C++, 86

226


, 201
, 29, 73
, 85
, 21
, 199
, 29, 73
* (), 142, 144
>, 142, 144
auto_ptr, 143
STL (
), 29
, 148
, 73, 99
, 51
, 99
, 140
, 140
, 129
$, 73
STL, 82
new, 140
, 99
, 193
new, 120
, 84
, 142
, 21, 50
SFINAE, 202
, 95

, 51
, 62
, 13

, 62
, 208
, 201, 205

g, 199
makePFun, 201
, 101
,
, 93

, 85


,
, 113

(ADL),
96, 97
, 96
, 99
, 24
, 24
, 194

ArrayDeletePolicy, 193
NoDeletePolicy, 193
PtrDeletePolicy, 193
Stack, 192
, 152

, 135138
, , 57
, 33
, 138
, 83
$ STL ,
83
(abort),
118, 136
, auto_ptr, 144
, 78, 88, 209
, 55
SList<T>::operator =, $,
168
String::operator =, $ , 56,
132
, 59
, 60
, 57

, 54
, 60
, 57
, 56
, 57
, 57

, 93
using, 91

, 91
, 90
using, 92
, 93
, 91
, 92
, 107

Action, 79
Circle, 111
Meal, 106
PlayMusic, 79
Shape, 111
Spaghetti, 106
, 92

, 35, 41
, 35, 82
, , 128

AnAlloc, , 170
AnAlloc::rebind, $, 171
,
171
,
, 28

, ( ),
56

ContainerTraits<const char *>, ,


183
ContainerTraits<ForeignContainer>,
, 183
, 185
, 181, 185
, 185

ContainerTraits, 182
ContainerTraits< vector<T> >, 185
ContainerTraits<const T *>, 184
ContainerTraits<T *>, 184

227
, 185
,
, 137
, , 137
,
, 135
new
append, , 122
operator new, , 120
, 54
, 31
STL (
), 29 31
, 131
$
, 83
,
163, 180, 181, 193, 208
, 42
static, 216
virtual, 216

, 171
, 95, 214
, 58

, 39
, 181, 185
class typename, 216

, 60
, 128
Handle, 127
,
216
,
119
, 59

, 124
, 56

, 173

$, 212
, 150

228

Heap<const char *>::pop, $


, 160
Heap<const char *>::push, $
, 153, 161
SFINAE, 203
,
173
, 177
, 159
, 16
, 177

Java C++
, 100

, 71
$, 95

, 199
, 32
, 104
, 32
, 34
, 34
, 72
, 34
, 72
, 34
, 34
, 32
(STL),
29 31
,
$, 68, 70
,
, 44
, , 93
,
, 24


, 40

, 195


,
44
, 27

$, 69
, 66
new operator new,
120, 123, 139
, 85
, 57
, 32

, 40
C++, 86
, 150
$, 167

, 185
, 180
, , 47
, 185
, ,
180

, 41
.
, 147
, 148
, 41
, 41
, 104
, 65
, 32
, 177
, 41
, 147

void, 104
$, 66


, 40

, 40
,
, 40

229


, 72
, 72
, 152

, 42
, 43

, 43

, 43
, 43
,
42
, 61
, 76
, 62
, 62
, 63
, 61
, 63
, 62
$
, 68

$, 76
, 66
$, 62
, 68
, 68
, 69
, 68, 70
,
, 66
, 29, 141
, 29, 148
, 142
auto_ptr, 144
, 142
, 209
, 209
, 198
, 201

, 199
, 62

RAII, 136

,
118
, 138
, 57
, 135

, 165

auto, 217
register, 217
, 172

, 110
Circle, , 112
Employee, , 110
Shape, , 112
Temp, , 110
, 37

aFunc, 92, 119


append, 122
begForgiveness, 63
cleanupBuf, 122
f, 137
fibonacci, 74
g, 199
getInfo, 109
integrate, 75
operator new, 120
popLess, 81
scanTo, 42
someFunc, 117
String::operator +, 57
strLess, 153
swap, 207
, 200

, 35
, 41, 43
, 35, 82
, 119
, 72
,
, 93

230
$
App::startup, 87
Button::setAction, 133
Fib::operator (), 73
Handle::operator =, 60
Handle::operator delete, 125
Handle::operator new, 125
Handle::swap, 59
Heap<const char *>::pop, 160
Heap<const char *>::push, 153, 161
String::operator =, 56, 132
String::String, 57
X::getValue, 50
X::memFunc2, 98
X::X, 130
$, 76
, 95
, 95
, 87
, 127

, 68

$, 76
, 66
, 68
, 68
, 69
, 68, 70
, 169
, 44


, 147
, 44, 46
new, 120

, 155, 177, 185


Heap<T *>::push,
$, 156

ContainerTraits< vector<T> >, 185
ContainerTraits<const T *>, 184
ContainerTraits<T *>, 184


Heap<T *>, 155
IsArray, 176
IsPCM, 177
IsPtr, 174

delete, 125
new
Handle, , 124
Handle::operator new, $
, 125
MyHandle, , 124
,
, 66
$, 169
AnAlloc::rebind, 171
SList<T>::operator =, 168
SList<T>::SList, 169
SList<T>::sort, 169
, , 52

$
Array<T,n>::operator ==, 211
Heap<T *>::push, 156
Heap<T>::pop, 152
Heap<T>::push, 152
SList<T>::empty, 166
Stack<T>::push, 175

App, , 87
App::startup, $, 87
MyApp, , 88
, 88
C++, 86
, 37

, 155
, 150
, 170
, 171
, 150

, 37
, 155
, 150
, 185

231


, 150

, 185
, 150
, 158, 177
, 154, 177, 198
C++
, 86
, 142
, 165, 172
$, 169

AnAlloc, 170
Array, 210
ArrayDeletePolicy, 193
CanConvert, 205
CheckedPtr, 141
ContainerTraits, 182
ContainerTraits< vector<T> >, 185
ContainerTraits<const T *>, 184
ContainerTraits<T *>, 184
Heap, 151, 159
Heap<T *>, 155
IsArray, 176
IsClass, 204
IsInt, 173
IsPCM, 177
IsPtr, 174
MFunc, 76
NoDeletePolicy, 193
PFun1, 200
PFun2, 198, 200
PtrCmp, 156
PtrDeletePolicy, 193
PtrList, 162
PtrVector, 42
ReadonlySeq, 180
SCollection, 163
Seq, 179
SList, 166, 171
Stack, 176, 189, 192
Wrapper1, 189
Wrapper2, 190
Wrapper3, 190

aTemplateContext, 130
cast, 195

extractHeap, 154
fill, 163
g, 199
makePFun, 198, 201
min, 196
process, 37, 178, 180, 182
process_2d, 37
repeat, 197
set_2d, 34
slowSort, 209
swap, 33, 58
zeroOut, 197

, 105

,
auto_ptr , 144

, 154, 177

ContainerTraits<const char *>, 183


ContainerTraits<ForeignContainer>,
183
Heap<char *>, 154
Heap<const char *>, 152

Heap, 151
IsInt, 173

Array<Circle,7>, 211
Heap<double>, 161