Professional Documents
Culture Documents
, ,
.
,
, ,
++. ,
++. ,
, !
, :
++
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),
.
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
$
.
. (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 );
$ :
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
. 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
// !
. ,
(. 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
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
$ 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 );
// !
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 () $
, 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
$
. 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;
66
15
2 ). , , , $
, Circle () Shape () $
. ++ ,
Circle * Shape *. Shape * Circle * ,
. $
Shape, Circle. ( $
: .)
:
$
, $
$
. ,
, $
. .
class Shape {
//...
Point center_;
//...
};
class Circle : public Shape {
//...
double radius_;
//...
};
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 = ˆ
(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
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
$
:
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;
// ! !
// , !
// !
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
// ! 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. : ?
,
.
. ,
$
.
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 ? (ob+delta == subj) : (subj == 0)
// !
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
{ 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
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 |
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
);
* );
);
*, 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
throw( bad_alloc );
) throw( bad_alloc );
) throw();
* ) throw();
// operator new
// new
// operator delete
// delete
,
$
127
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()
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
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. $
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
IsPtr , IsInt.
, $
$ $
. , IsPtr
, IsInt. $
. ( $
59 SFINAE.)
,
:
175
$ $
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
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
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
$
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
$
: . $
, $
, $
( , ).
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
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
, 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
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
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
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
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