Академический Документы
Профессиональный Документы
Культура Документы
......................................................................................................................................... 9
..................................................................................................................... 9
1. ............................................................................................ 11
1. ++? .................................................................... 13
++......................................................................................................................................................... 13
++................................................................................................................................ 15
................................................................................................................................ 16
...................................................................................... 17
2. ++ ...................................................................................................................... 19
........................................................................................................................ 19
const............................................................................................................................................................ 19
....................................................................................................... 23
.................................................................................................................. 25
.................................................................................................................................... 25
................................................................................................................................................. 28
................................................................................................................................................. 29
...................................................................................................................................... 33
.......................................................................................................................................... 33
............................................................................................................................................ 40
............................................................................................................................................ 41
............................................................................................................................ 46
3. ............................................................................ 55
? ............................................................................................. 55
................................................................................................................................................... 55
.................................................................................................................................... 56
........................................................................................ 56
................................................................................................................................ 57
...................................................................................................................... 57
................................................................................................................. 57
................................................................................................... 58
................................................................................................................................ 58
.................................................................................................. 59
!...................................................................................... 59
............................................................................................................................................. 59
......................................................................... 59
.............................................................................. 60
................................................................................ 60
............................................................................................. 60
4. .......................................................................................................................... 63
4
ANSI ........................................................................................... 63
.................................................................................................. 63
.......................................................................................................... 66
............................................................................................................... 67
............................................................................................... 69
............................................................................................................................. 69
2. .................................................................................................. 71
5. ............................................................................................................... 73
...................................................................................................................................... 73
................................................................................................................. 75
-> ............................................................................................................................................. 75
................................................................................................... 75
.................................................................................................................... 76
............................................................................................. 77
?..................................................................................................... 78
................................................................................................................................................. 78
NULL ............................................................................................................... 78
........................................................................................................................... 80
.............................................................................................................................................. 82
6. ..................................................................... 85
............................................................................................................ 85
...................................................................................................................................... 86
............................................................................................................................................ 87
............................................................................................................................................... 87
............................................................................................................................................. 88
............................................................................................... 89
C++ ..................................................................................................................................... 90
? ................................................................................................................................... 90
.................................................................................................................................... 90
................................................................................................................. 92
/.................................................................................................................. 92
7. ......................................................................... 93
......................................................................................................................... 93
....................................................................................................................... 93
........................................................................................................ 94
............................................................................................................................ 96
............................................................................................................................................................. 96
.................................................................................... 97
................................................................................................................................................. 98
......................................................................................................................... 99
................................................................................................... 102
...................................................................................................................................... 103
............................................................................................................... 103
.................................................................................................................... 105
..................................................................................................................................... 106
................................................................................................... 106
....................................................... 107
................................................ 107
................................................................................................................................................ 107
.................................................................................................................................................... 108
8. , ....................................................................... 111
[] .......................................................................................................................... 111
5
........................................................................................................... 111
[] ............................................................................................... 112
........................................................................................................ 112
[] ........................................................................................ 113
[].................................................................................................................... 113
...................................................................................................................................................... 114
................................................................................................. 114
......................................................................................................... 115
-> ........................................................................................ 116
- ................................................................................................................................ 117
.................................................................................................................................................. 117
............................................................................................................................ 118
.......................................................................................................................... 118
? ............................................................................................................................................. 119
, ............................................................................................ 119
................................................................................................................................... 120
....................................................................................................... 121
............................................................................................................................. 123
....................................................................................... 124
...................................................................................................................... 126
...................................................................................................... 127
................................................................................................................................ 129
..................................................................................................................................................... 131
9. .............................................................. 137
........................................................................................................................ 137
............................................................................................................................................... 137
.................................................................................................................................................... 138
? .................................................................................................................................................. 138
................................................................................................................................. 138
.................................................................................................................. 139
......................................................................................................................................... 140
...................................................................................................... 141
................................................................................................................................. 144
......................................................................................................................... 145
.............................................................................................................................. 145
....................................................................................................................... 146
ConstPtr......................................................................................................................................... 147
LockPtr .......................................................................................................................................... 149
..................................................................................................... 150
............................................................................................................ 151
.................................................................................................................................................... 152
................................................................................................................................................... 152
.......................................................................................................................... 152
............................................................................................................ 153
........................................................................................................................ 154
............................................................................................................................. 154
................................................................................................................ 155
3. ..................................................................................................................... 157
10. ....................................................................................... 159
......................................................................................................... 159
......................................................................................... 160
...................................................................................................................... 160
...................................................................................................... 161
..................................................................................................................... 162
6
.................................................................................................................................... 163
........................................................................................................ 164
......................................................................................................... 165
................................................................................................ 166
........................................................................................................................................... 167
11. ............................................ 169
.......................................................................................................................... 169
make- .......................................................................................................................................... 170
make- .................................................................... 170
......................................................................... 170
...................................................................... 171
...................................................................................................................... 172
: ............................................................ 172
=!.................................................................................... 173
...................................................................................................................................... 173
.............................................................................................................................. 174
............................................................................... 175
............................................................................................................ 176
.......................................................................................................................................... 177
12. ................................................................................................ 179
.............................................................................................................................. 179
........................................................................... 180
.......................................................................................................................... 180
.............................................................................................................................. 181
............................................................................................................................. 181
................................................................................................................................. 183
..................................................................................................................... 184
.................................................................................................................. 185
.................................................................................................... 187
....................................................................................................... 189
................................................................................................... 189
............................................................................................................................................ 189
............................................................................................... 189
................................................................................... 189
4. .................................................................................................... 191
13. ......................................... 193
NEW DELETE ................................................................................................... 193
...................................................................................................... 193
new delete................................................................................................. 196
new .................................................................................................................... 197
.................................................................................................... 197
.......................................................................................................... 198
?................................................................................................... 199
............................................................................................................................ 199
..................................................................................... 200
............................................................................... 200
......................................................................................... 200
................................................................. 200
........................................................................................................................................... 204
14. .............................................................................. 205
................................................................................................................................ 205
........................................................................................................ 205
7
............................................................................................................................ 208
....................................................................................................................... 208
........................................................................................................................................ 210
...................................................................................................... 210
.............................................................................................................. 211
............................................................................................. 211
....................................................................................................... 212
................................................................................................................. 213
.................................................................................................. 213
............................................................................................................................. 214
................................................................................................................................. 214
................................................................................................................................. 215
........................................................................................................ 215
............................................................................................................. 215
.................................................................................................................. 216
15. ..................................................................................................... 217
.................................................................................................................................... 217
, ? ...................................................................................................... 217
................................................................................................................................... 220
, .................................................................................................. 223
.............................................................................................................. 223
................................................................................................................................. 223
.................................................................................................................................................. 227
........................................................................................................ 229
.................................................................................................................................... 229
....................................................................................................................... 229
............................................................................................................ 232
................................................................................................................................... 233
: C++ ....................................................................................... 234
.............................................................................................................................. 236
VoidPtr ............................................................................................................................ 236
........................................................................................................................ 237
............................................................................................................ 238
............................................................................................................................ 238
........................................................................................................................................... 239
............................................................................................. 239
............................................................................................................................................. 239
16. ................................................................................................................. 241
.............................................................................................................................................. 241
................................................................................................................................................ 241
................................................................................................................................. 242
................................................................................................................................. 243
....................................................................................................................... 244
................................................................................................ 245
............................................................................................................... 245
............................................................................................................. 245
.......................................................................................................... 246
............................................................................................................................... 248
........................................................................................................................................... 251
................................................................................................................................... 251
........................................................................................................... 251
................................................................................................ 251
? .................................................................................................... 252
..................................................................................... 252
.................................................................................................... 252
.............................................................................................................................. 253
8
.................................................................................................................................... 254
................................................................................................................... 254
......................................................................................................................................... 255
......................................................................................................... 255
........................................................................................................................... 255
. JAVA C++ ..................................................................................................... 257
, , ,
. , ,
. , ego . ,
.
, - , ,
.
, , ,
AP Professional. ,
, . ,
, !
(John Trudeau) Apple Computer,
++. ,
, ,
, , .
++ -
. (Neal Goldstein),
(Larry Rosenstein), (Eric Berdahl), (John Brugge),
(Dave Simmons) (Dave Buell). ,
, .
Microsoft Corporation, ,
90
90 . Microsoft, , ,
, . ,
Microsoft, Microsoft ,
.
(James Coplien), , Advanced C++
Programming Styles and Idioms .
++. ,
.
, (Bjarne Stroustrup) ,
. , SmallTalk ,
. ++ ,
, .
, , . ++
- .
, .
, , ( , IEEE
Computer) ,
10
++. , , . ,
, .
. -,
- , , , .
++ ,
, , , .
,
, .
, .
, ,
, .
++, - : (
), ( ), ( ) ..
, (<< >>).
, , ?
, .
, ,
. ,
, , ,
. : ,
. ,
.
1998 .
1
:
++?
.
,
,
++.
1
++?
++
++ , . , ,
. -,
++ - . ! . ++
, (, ,
) //. ,
, (, )
.
14
! . ++ , -
. Smalltalk, , ,
? ++ Cobol 90-, ,
. ++
, . ,
++ .
, ?
! , . , ? . ++
, .
( ++
), .
- , ,
. , Smalltalk
Lisp, , -
. ++ . ,
.
. ++
: ,
. ++ .
.
(, i++).
, , :
cout << 17 << endl << flush;
++. ,
, .
,
, . ,
. , ,
-.
, .
? ,
,
. - ,
! . ,
. i++
, i:=i+1, x=17+29 , (setq
x(+17, 29)). ,
. ++ .
, ,
++.
++ Lisp, Smalltalk ( )
.
, .
, , ,
( )
. ,
, ++ . , -
,
. ,
, . ,
, - .
. , , .
, ,
. , ?
15
++, ,
: , . .
++ .
. .
, .
, . ,
, .
; ,
.
. ,
.
++
C++ , , .
- ? ,
, -
. ,
.
C++. ,
, . .
C++, :
.
.
.
C++,
. ,
,
.
C++. ,
C++
, . ,
/ cout cin. 1
, C++
. 1 ,
, C++.
(indirection) ,
: ,
, , .
. ,
(delegation), -
. , C++ , ,
, .
(pointer); . C++
. , , ,
; ; ;
,
,
. , , ,
.
,
.
- , C++
16
- . ,
(homomorphic derivation)
C++.
-. ,
,
. C++
.
(memory space) ,
. C++ new delete, ,
. , , ,
.
- , ,
Microsoft, Apple Taligent. ,
,
.
, C++. ,
, .
.
. ,
C++ , , , ,
, .
. ,
,
, , . .
-
C++.
C++ ,
;
. , ,
. 2
. 3
, . 4
ANSI
, .
2 .
, , .
3 C++.
.
, .
,
. , ,
.
4 C++ .
,
, C++,
. ,
C++, , ,
-
.
17
: . ?
, ,
,
. , ,
, .
. ,
. , , -
, .
,
, .
, . ,
.
(inline) ,
.
:
class Foo {
public:
void MemberFn();
};
inline void Foo::MemberFn()
{
...
}
:
class Foo {
public:
void MemberFnO {...};
};
,
, . .
,
, .
.
, ,
!
2
++
C++ , C++ (
) . ,
, C++ .
, -
. Annotated Reference Manual
.
,
. C++!
, , .
: .
const
const, ,
C++. , - ,
.
const, , .
, .
.
const int j = 17; //
j = 29; // ,
const int i; // ,
, ,
, .
, ,
. i ,
. int ,
const int j=17; , int j(17).
, .
, .
,
, .
const i = 17;
int& j = 1; // , j
20
, , j. ,
, . ,
, ,
.
const #define
:
const int i = 17;
#define i 17;
, ,
. , - ,
.
, .
.
() :
. C++ ,
.
class Foo {
public:
enum Status { kOpen = 1, kClosed };
};
// -
Foo::Status s = Foo::kOpen;
,
. , kOpen kClosed
.
, .
(, ).
, :
. ;
, .
const int* p;
int i = 17;
p = &i; //
*p = 29; //
.
class foo {
public:
int x;
};
const foo* f = new foo;
f->x = 17; // ,
21
: ,
.
int i = 17;
int j = 29;
int* const p; // !
int* const p1 = &i; //
*p1 = 29; // ; , ,
//
p1 = &j; //
(- !)
. .
int i = 17;
int j = 29;
const int* const p; // .
const int* const p1 = &i; //
*p1 = 29; //
p1 = &j; //
,
.
void f(const int* p)
{
*p = 17; //
int i = 29;
p = &i; // , ?
}
// -
int i = 17;
f(&i); // ,
, , .
-.
, .
void f(const int& p)
{
p = 17; //
int i = 29;
p = i; // ( )
}
// -
int i = 17;
f(i); //
22
, ,
, .
void f(int*);
int i = 17;
const int* p = &i;
const int j = 29;
f(&i); // , i
f(p); //
f(&j); // , j -
,
. f
, .
this .
, this
, . const
; , ,
.
class foo {
private:
int x;
public:
void f() const;
void g();
};
void h(int*);
void m(foo*);
void foo::f();
{
x = 17; // :
this->g(); // : g
h(&x); // : h x
m(this); // : m()
}
this.
foo this const foo* this;. .
, g - foo,
; , .
this.
.
C++ const,
. , this,
. ,
, ,
, .
,
23
. :
(), .
, C++ C. C++
, ,
. , .
int x = 17;
,
.
{
int i;
foo f(constructor_args);
// i f
}
.
. ,
, , ,
.
:
{
int i;
foo f;
SomeFunction(&f);
}
SomeFunction , .
SomeFunction - ,
f.
SomeFunction , ,
- SomeFunction,
!!!
.
(heap), new.
foo* f = new foo(constructor_args);
. new
. ?
, :
24
- delete . ;
, .
.
, .
, (dereferencing)
. , .
{
foo f;
foo* p = &f;
f.MemberFn(); //
p->MemberFn(); //
p = new foo;
foo& r = *p; //
r.MemberFn(); // , p->MemberFn()
}
, . ->
. , (. ->)
(member selectors).
, , ,
- .
delete ,
. ( ) , ,
, , ,
. , C++ new
.
. delete , .
new ,
. delete ,
.
, ,
:
1.
.
2. delete.
, :
.
, ,
(, ). new
( , ) , ,
.
. ,
new, ,
.
25
,
,
. Foo
PFoo. Foo;
. ,
. , operator Foo*() PFoo ,
Foo* , g().
class PFoo {
private:
Foo* f;
public:
PFoo() : f(new Foo) {}
~PFoo() { delete f; }
operator Foo*() { return f; }
}
void g(Foo*);
{
PFoo p;
g(p); // operator Foo*()
// p, Foo
}
, , ,
operator Foo*(), PFoo.
.
. ,
- , . ,
,
.
ANSI-
(exception).
, .
, . , ,
.
C++
. , ,
. , C++
. , ,
.
:
;
;
;
;
.
26
, , .
. ,
.
C++ , .
, .
class Foo {
public:
static int y; //
static void GFn(); //
int x; //
Foo(); //
void Fn(); //
typedef int (*IntFn)(); //
enum Status { kOpen = 0, kClosed }; //
struct Bar { //
int a;
int b;
static void BarFn();
}
private:
void Hn();
};
.
, a GFn() ,
Foo. Foo ,
:::
Foo::Foo()
{
GFn(); // Foo
}
void f()
{
Foo::GFn(); //
}
,
.
, Foo Fn(), (instance)
. - , . ->.
(, , C++)
,
27
. ,
,
:
Foo f;
f.Gfn(); // , Foo::GFn();
C++ . ,
. , ;
public, private, protected . ,
: (public),
C++.
, .
?
:
.
-, .
-, .
C++
. , ,
C++ (
). (-
), v-,
.
C++ .
.
, ,
:
( ).
-.
.
, , ,
.
,
.
(private) (public). ,
, ,
. ,
.
, ,
.
C++ ,
.
.
28
, .
.
:
// Foo.cpp
typedef int Symbol;
// Bar.cpp
typedef void (*Symbol)();
,
. #include. Symbol
, ,
-. ,
, .
, .
// Foo.cpp
int Symbol;
// Bar.cpp
void (*Symbol)();
,
. ,
, .
;
. ,
.
// Foo.cpp
static int Symbol;
// Bar.cpp
static void (*Symbol)();
static, ,
; .
, ,
:: :
::Fn(); //
int x = ::i; // x
::SomeType y; //
,
, .
C++ . ,
. ,
, .
.
, ,
.
void Fn();
29
void Fn(int);
void Fn(long); // , long int
int Fn(int); //
int Fn(char*); // ,
void Fn(int, char*);
void Fn(char*, int); // ,
void Fn(char* s, int x, int y = 17); //
Fn(hello, 17); //
, .
( =17) ,
(
).
, ,
.
, .
class Foo {
public:
void Fn();
void Fn() const; // !
};
Foo* f = new Foo;
f->Fn(); //
const Foo* f1 = f;
f1->Fn(); //
C++ ( , ) ,
, , .
, .
, (visibility) C++.
;
. ,
.
,
, .
class Mixin {
private:
int x;
protected:
int y;
public:
Mixin();
Void a();
};
30
class Foo : private Mixin {...};
class Bar : public Foo {...};
Mixin ().
Foo, Mixin::A(). Mixin ,
Foo ( r ). Foo (), Bar
.
,
.
class Foo {
protected:
virtual void Fn();
};
class Bar : public Foo {
public:
virtual void Fn();
};
Foo Fn() , .
.
.
class Foo {
private:
int x;
public:
void Fn();
};
class Bar : public Foo {
private:
int x; //
public:
void Fn(); //
};
//
Bar *b = new Bar;
b->Fn(); // Bar::Fn()
Foo* f = b; // , Foo
f->Fn(); // Foo::Fn()
. Foo
Foo::. Bar r::.
, ,
. Fn() ,
.
C++ .
,
. , ,
. . ,
virtual .
31
,
, .
DWIMNIS: Do what I mean, not what I say ( ,
, , ). , C++ ,
( ) .
Bar::Fn():
class Foo {
public:
virtual void Fn();
};
class Bar {
public:
void Fn(); //
};
Bar* b = new Bar;
b->Fn(); // Bar::Fn()
Foo* f = b;
f->Fn(); // Bar::Fn()
. -,
, Foo::Fn(). -,
, Fn() , .
.
, ,
, .
? ? , .
class Foo {
public:
virtual void Fn();
virtual void Fn(char*);
};
class Bar {
public:
virtual void Fn(int); // ,
};
, - ,
. :
Fn() r* , void Fn(int).
Bar*.
Bar* Foo* , Foo,
void Fn(int). , ,
Bar::Fn() . , virtual
.
- , ,
, , - .
, .
. , :
, , .
32
- (friend).
, ,
, .
, . ;
- , .
class Foo;
class BarBar {
public:
int Fn(Foo*);
};
class Foo {
friend void GlobalFn(); //
friend class Bar; //
friend int BarBar::Fn(Foo*); //
friend class DoesNotExist; // .
private:
int x;
struct ListNode {
ListNode* next;
void* datum;
ListNode() : next(NULL), datum(NULL) {}
} head;
protected:
int y;
public:
void G();
};
void GlobalFn()
{
Foo* f = new Foo;
f->x = 17; // -
}
class Bar {
private:
Foo* f;
public:
Bar() : f(new Foo) {}
void WalkList();
};
void Bar::WalkList()
{
Foo::ListNode* n = f->head.next;
for (; n != NULL; n = n->next)
cout << n->datum << endl;
}
int BarBar::Fn(Foo* f)
{
return f->x;
}
33
, public,
protected private. ,
; , .
Foo . Foo,
. , -
DoesNotExist. , ,
. Foo.
, . ,
.
, , ,
.
, , ,
, .
, (,
).
, C++
, .
, ,
.
class Foo {
public:
Foo();
};
class Bar : public Foo { // 1.
public:
Bar();
};
class BarBar {
private:
Foo f; // 2.
};
Foo f; // 3. Foo
Foo* f1 = new Foo; // 3. ,
(. ) Bar -
Foo,
Foo . , f
BarBar, Foo . ,
Foo
.
, , .
, .
,
. -
34
, ,
, ,
.
class Foo {
public:
Foo(char*);
};
Foo f; // !
class Bar : public Foo {
public:
Bar();
};
Bar::Bar()
{
// ! Foo
}
, C++ :
. ,
.
class Foo {
public:
Foo(char*);
};
class Bar : public Foo {
public:
Bar(char*);
};
class BarBar {
private:
Foo f;
int x;
public:
BarBar();
};
Bar::Bar(char* s) : Foo(s) {...}
BarBar::BarBar : f(Hello), x(17) {...}
Bar
Foo. ,
. Bar
, ,
Foo. BarBar
( ) f .
(
):
BarBar::BarBar() : f(Hello)
{
x = 17;
}
35
0 (
C++) int ,
17.
- . ,
,
, .
,
(, ,
).
, ,
.
, ,
.
.
, , :
1.
( , : ,
).
2.
.
3. ,
.
,
... . . , .
,
. ,
, .
(copy constructor) :
class Foo {
public:
Foo(const Foo&);
};
Foo::Foo(const Foo& f)...
.
.
void Fn(Foo f) {...}
void Gn(Foo& f) {...}
Foo f;
Foo f1(f);
Foo f2 = f; // , !
Fn(f); //
const Foo f3;
Gn(f3); //
//
. Foo f1(f);
Foo, Foo . ,
36
Foo . ,
; , . , Foo
; ,
.
Foo f2 = f - =,
. ,
, :
? , .
, , .
Fn() Foo.
, Fn().
, .
Gn(), , ,
C++ - :
, ! ,
. ,
, , .
Gn() , .
.
1. ,
.
2. ,
.
,
... . . , ? ,
.
, , .
, , ,
.
.
class Foo {...};
class Bar : public Foo {
private:
Foo f;
public:
Bar(const Bar&);
};
// ,
Bar::Bar(const Bar& b)
{
// !
//
//
}
// ,
Bar::Bar(const Bar& b) : Foo(b), f(b.f) {...}
37
,
.
Foo . 99 100 ,
; , .
, .
, ( b
Foo Foo(b)).
.
,
.
class Serialized {
private:
static int NextSerialNumber;
int serialNumber;
public:
Serialized(const Serialized&);
Serialized();
int SerialNumber();
};
// Serialized.cpp
int Serialized::NextSerialNumber = 0;
Serialized::Serialized() : serialNumber(NextSerialNumber++)
{
}
Serialized::Serialized(const Serialized&) : serialNumber(NextSerialNumber++)
{
}
int Serialized::SerialNumber()
{
return serialNumber;
}
ac ,
, ,
.
,
. ;
new (
, ). ,
,
. ,
. - .
, ( )
.
class Foo {
protected:
Foo();
};
38
class Bar : public Foo {
public:
Foo* Fn();
};
Foo Bar::Fn()
{
return new Foo; //
}
, , Foo .
, ! . Foo
Bar Foo. ,
.
(anonymous instance) , ... , .
struct Point {
int X;
int Y;
Point(int x, int y) : X(x), Y(y) {}
};
double distance(Point p)
{
return sqrt(double(p.X) * double(p.X) + double(p.Y) * double(p.Y));
}
double d = distance(Point(17, 29));
distance() .
. ,
.
Point,
.
.
C++,
.
, ,
. ,
,
. ,
:
1. -
0.
2. , ,
.
3. .
, main()
.
39
4. , (
.), .
3 , ,
.
.
.
.
// file1.cpp
Foo foo;
Foo* f = &foo;
// file2.cpp
extern Foo* f;
Foo f1(*f); //
, . F*
f = &foo; ,
(-) . ,
, foo . , ,
file1.cpp
file2.. file2.cpp , f 0 (NULL
), .
,
.. .h
,
.. 0 1 ,
.. 1 0
.
// Library.h
class Library {
private:
static int count;
static void OpenLibrary();
static void CloseLibrary();
public:
Library();
~Library();
};
static Library LibraryDummy;
inline Library::Library()
{
if (count++ == 0)
OpenLibrary();
}
inline Library::~Library()
{
if (--count == 0)
CloseLibrary();
}
// Library.cpp
int Library::count = 0; //
int aGlobal;
40
Foo* aGlobalFoo;
void Library::OpenLibrary()
{
aGlobal = 17;
aGlobalFoo = new Foo;
}
void Library::CloseLibrary()
{
aGlobal = 0;
delete aGlobalFoo;
aGlobalFoo = NULL;
}
. : .h
., - Library.cpp. ,
, . ,
LibraryDummy. .,
Library.h, LibraryDummy . main()
exit() .
LibraryDummy. , OpenLibrary() CloseLibrary()
.
,
iostream. ,
, , .
, (
, )
delete.
.
, .
, ,
, ,
, ..
,
. ,
,
.
main() exit().
C++ . base*
( ), , .
class Foo {
public:
~Foo();
};
41
class Bar : public Foo {
private:
int* numbers;
public:
Bar() : numbers(new int[17]) {...}
~Bar();
};
Bar* b = new Bar;
delete b; // Bar::~Bar()
Foo* f = new Bar;
delete f; // ! Foo::Foo()!
f , numbers,
, . ,
; (, ,
void*) Bar: :~().
,
.
!
. , ,
20 , 220 ! C++
.
: . ,
.
, delete,
, . , ,
, - .
class Foo {
public:
~Foo();
};
Foo* f = new Foo;
f->Foo::~Foo();
, C++.
C++ . ,
.
=.
Foo f;
Foo f1;
f1 = f;
. f f1 -
, : ,
42
f, , f1. . Foo
, C++ .
= ,
. , ,
, =. ,
, ,
.
class String {
private:
char* s;
public:
String(char*);
~String();
void Dump(ostream& os);
};
String::String(char* str) : s(NULL)
{
if (str == NULL) { // NULL
s = new char[1];
*s = \0;
}
else {
s = new char[strlen(str) + 1];
strcpy(s, str);
}
}
String::~String()
{
delete s;
}
void String::Dump(ostream& os)
{
os << \ << s << \;
}
String* s1 = new String(Hello);
String* s2 = new String(Goodbye);
s2 = s1;
delete s1; // , ...
s2->Dump(); // ! --!
delete s2; // , ! --!
s2->s s1->s.
, ,
. ,
Goodbye, String* s2 = new String( "Goodbye");. ;
s1 , s1.
s2->s. s2->s
. s2,
. C++!
43
, .
, , .
= .
, , ,
. = , =
. ,
. =
. =.
Foo f;
Foo f1 = f; // ; f1
f1 = f; // : f1
= , ,
. , ,
= .
:
1.
. =
= .
2.
. =
= .
. ,
. .
=
= .
=, : & X::operator=(const X&).
class String {
private:
char* s;
public:
String(char*);
~String();
String(const String&); // ,
String& operator=(const String&);
void Dump(ostream& os);
};
String::String(char* s) : s(NULL)
{
if (str == NULL) { // NULL
s = new char[1];
*s = \0;
}
else {
s = new char[strlen(str) + 1];
strcpy(s, str);
44
}
}
String::~String()
{
delete s;
}
String::String(const String& s1) : s(NULL)
{
s = new char[strlen(s1.s) + 1];
strcpy(s, s1.s);
}
String& String::operator=(const String& s1)
{
if (this == &s1) return *this;
delete s; //
s = new char[strlen(s1.s) + 1];
strcpy(s, s1.s);
return *this;
}
void String::Dump(ostream& os)
{
os << \ << s << \;
}
=
. , .
=, (
, ):
1. , x=x;.
, . ,
, .
2. .
3. .
4. *this.
= *this, =b=. C++,
, .
, =(b=).
. , = C++
. =,
;
.
(, int),
=, .
(, String) .
- . -
. ,
= .
class Foo {
45
public:
Foo& operator=(const Foo&);
};
class Bar {
public:
// =
};
class FooBar {
private:
Foo f;
Bar b;
public:
FooBar& operator=(const FooBar&);
};
FooBar& FooBar::operator=(const FooBar& fb)
{
if (this == &fb) return *this;
f = fb.f; // = Foo
f = fb.b; // =
return *this;
}
, ,
=. .
.
, , .
:
class Foo {...}
class Bar : public Foo {
public:
Bar& operator=(const Bar&);
};
Bar& Bar::operator=(const Bar& b)
{
if (this == &b) return *this;
this->Foo::operator=(b); // -?
return *this;
}
, (, *((Foo)this)=b;),
. . ,
, Bar Foo . ,
Foo::operator= . ,
, Foo::operator=.
=
= . ,
. & X::operator=(const &)
,
.
46
class String {
//
public:
String& operator=(const String&); //
String& operator=(char*); //
String& operator=(int); // atoi()
};
=
.
String char* , .
. ,
( ) .
C++ .
, Add ,
+ . , ,
. -,
. -, .
,
.
(, +) :
. C++ operator,
.
class Foo {...}
Foo x, y, z;
z = x + y; // ()
z = operator+(x, y); // ( )
z = x.operator+(y); // ( )
, , ,
, ,
.
. .
, , ,
. ( ! ~)
. ,
( , .
->).
(, ).
, ,
( ).
, C++. -
#$%^&, C++ .
,
, ,
+. , ,
,
.
47
,
.
class String {
friend String& operator+(const String&, const String&);
private:
char* s;
public:
// ..
}
String& operator+(const String& s1, const String& s2)
{
char* s = new char[strlen(s1.s) + strlen(s2.s) + 1];
strcat(s, s1.s, s2.s);
String newStr(s);
delete s;
return newStr;
}
String s1 = Hello;
String s2 = Goodbye;
String s3 = s1 + s2;
, (
). .
operator+ , s, :
char*, , -
. operator+
String, ,
String.
, , =,
[], () -> .
,
1 .
class String {
private:
char* s;
public:
// ..
String& operator+(const String&) const;
};
String& String::operator+(const String& s1) const
{
char* s2 = new char[strlen(s1.s) + strlen(s) + 1];
strcat(s2, s1, s);
String newStr(s2);
delete s2;
return newStr;
}
48
String s1 = Hello;
String s2 = Goodbye;
String s3 = s1 + s2;
.
, , ? :
,
. :
1. (, int double).
2. ,
.
,
.
, .
<< ostream.
ostream& operator<<(ostream& os, const String& s)
{
os << str.s; // ,
return os;
}
, , String,
, , iostream.h
ostream String. , - .
: , strlen
strcat, , char* const char*.
, , ,
. ,
, ,
.
String& String::operator+(const String& s1) const
{
char* s2 = new char[strlen((char*)s1.s) + strlen(s) + 1];
strcat(s2, (char*)s1.s, s);
String newStr(s2);
delete s2;
return newStr;
}
, , - ?
.
, :
.
class String {
private:
char* s;
public:
operator long(); // atol long
};
String::operator long()
49
{
// , ,
// ,
return atoll(s);
}
String s(1234);
long x = s; // operator long()
. ,
, ,
. , long().
Foo, Foo String,
operator Foo(). :
, , - ?
, .
, .
.
int? , int
, . ,
.
. ,
, .
.
.
, .
, , .
, . ,
,
.
class String {
private:
char* s;
public:
operator const char*() const { return s; }
operator char*():
};
String::operator char*()
{
char* newStr = new char[strlen(s) + 1];
strcpy(newStr, s);
return newStr;
}
, ,
.
C++ ,
, , .
, :
1. , .
50
2. ,
, .
, .
3. ,
.
,
, -
.
.
, , .
, .
,
. ,
, .
, .
3,
.
->
-> . .
class Pointer {
private:
Foo* f;
public:
Pointer(Foo* foo) : f(foo) {}
Foo* operator->() const { return f; }
};
Pointer p(new Foo);
p->MemberOfFoo();
Foo.
(*-) >,
->. ->,
; ,
->.
, ->.
/, -
, ->.
,
-> ( Foo*) ,
. ,
.
class Pointer2 {
private:
Pointer p;
public:
Pointer(Foo* foo) : p(foo) {}
Pointer operator->() const { return p; }
};
Pointer2 p(new Foo);
p->MemberOfFoo();
51
-> :
1. Pointer2::operator-> Pointer.
2. Pointer::operator-> Foo.
3. Foo* .
,
.
. , ,
.
[]
[] ,
.
class String {
private:
char* s;
public:
String(char*);
char operator[](int n) const; // n-
};
char String::operator[](int n)
{
//
return s[n];
}
[] ,
.
struct Index3 {
int X, Y, Z;
Index3(int x, int y, int z) : X(x), Y(y), Z(z) {}
};
class Array3D { // String
private:
//
public:
String& operator[](const Index3&);
};
String s = anArray[Index3(17, 29, 31)];
[] ,
.
()
, , .
, ,
. , C++
. () ,
.
, - .
52
class Function {
public:
int operator()(char*);
};
int Function::operator()(char* s)
{
cout << \ << s << \;
}
Function fn;
int x = fn(Hello); // cout Hello
() .
, . ()
.
new
, . C++
, .
new delete. new , ,
.
, int, char* .., .
new :
void* operator new(size_t bytes);
,
. new NULL;
(. 4). new
mall call ,
.
new , .
,
, , new.
class Foo {
public:
void* operator new(size_t bytes);
};
void* Foo::operator new(size_t bytes)
{
if (bytes < MAXBYTES)
//
else return ::operator new(bytes);
}
, new ,
.
: new
, . new
. ,
,
new.
class Pool { //
public:
virtual void* Allocate(size_t bytes);
53
};
void* operator new(size_t bytes, Pool* p)
{
return p->Allocate(bytes);
}
extern Pool* DefaultPool;
Foo* f = new(DefaultPool) Foo;
new Foo;
, .
delete
delete new
. ,
:
1. void operator delete(void* address);
2. void operator delete(void* address, size_t bytes);
; ,
.
, ... !
:
class Foo {
private:
int x;
public:
~Foo(); //
};
class Bar : public Foo {
private:
int y;
public:
~Bar();
};
Bar* b = new Bar;
delete b; //
Foo* f = new Bar;
delete f; // Foo, Bar
.
, .
:
1. .
2. .
3. , , , .
,
, ,
( , v-). ?
.
delete, new, ,
. , .
54
new, delete . ,
, , .
3
,
. , , , ,
, C++ .
, ,
. , , ,
- . .
C++, .
?
- ( ) :
class ListNode {
private:
ListNode* next;
void* data;
public:
ListNode(void* d, ListNode* n = NULL) : next(n), data(d) {}
~ListNode() { delete next; }
void* Data() { return data; }
ListNode* Next() { return next; }
};
- ?
, void*. , ,
. - - :
for (ListNode* n = listHead; n != NULL; n = n->Next())
f((Foo*)n->Data());
, void* ,
Foo*?
, , , . ,
, .
, -
? ,
, .
56
, , .
, , , ,
. delete void* ,
.
,
. void* ,
. ,
ListNode ,
. ,
.
, . ,
Foo - ListOfFoos.
, Foo . -
, , ? ,
,
. ,
.
#define:
#define ListNode(Type) \
class ListNode##Type { \
private: \
ListNode##Type* next; \
Type* data; \
public: \
ListNode##Type(Type* d, ListNode* n = NULL) : next(n), data(d) {} \
~ListNode() { delete next; } \
void* Data() { return data; } \
ListNode* Next() { return next; } \
};
\, ,
. ## .
,
. .
(inline),
, .
. #define
, ,
. , ,
- , .
#define. ,
. .
. C++
. . ,
\ ##.
57
, ,
(parameterized).
( ) .
,
template <c1ass Type>, Type
( ). , Type (
) ,
. ListNode,
, :
template <class Type>
class ListNode {
private:
ListNode<Type>* next;
Type* data;
public:
ListNode(Type* d, ListNode<Type>* n = NULL) : next(n), data(d) {}
~ListNode() { delete next; }
Type* Data() { return data; }
ListNode<Type>* Next() { return next; }
};
ListNode<Foo> list = new ListNode<Foo> (new Foo);
Foo* f = list->Data(); //
,
.
, .
template.... ,
. , ,
.h. .,
( ., ).
//
template <class Type>
Type* fn(Type* t);
//
template <class Type>
Type* fn(Type* t) {
// , Type
//
}
Foo* f = fn<Foo>(new Foo);
, .
, .
58
(
< >). ListNode ,
.
template <class Type>
class ListNode {
private:
ListNode<Type*> next;
Type* data;
public:
ListNode(Type* d, ListNode<Type>* n = NULL);
~ListNode();
Type* Data();
ListNode<Type>* Next();
};
template <class Type>
ListNode<Type>::ListNode(Type* d, ListNode<Type>* n = NULL)
: next(n), data(d)
{
}
template <class Type>
ListNode<Type>::~ListNode()
{
delete next;
}
template <class Type>
Type* ListNode<Type>::Data()
{
return data;
}
template <class Type>
ListNode<Type>* ListNode<Type>::Next()
{
return next;
}
: .h. ,
., .
.
< > , C++
. , <> ,
:
1. class .
2. .
3. .
,
.
59
. , C++
, C++...
.
.
, .
, .
, .
, <c1ass Type> <c1ass Type1, class
Type2>. , . -,
.
!
, , , .
,
. ,
.
template <class Type>
class B {...};
template <class Type>
class A {
B<A<Type>>* member; // !
};
.
. , ;
, .
, .
, ;
,
. ,
, APL-. ,
.
.
.
, ,
1000 .
1000 .
.
, ,
. ,
.h. .
, - ,
. , , ,
.
. ,
.h <>?
60
,
. , 99 100
, .
-
.
, .
. .
,
. (
, ), -
: .
.
.
class UnsafeNode { // ListNode
private:
UnsafeNode* next;
void* data;
public:
UnsafeNode(void* d, UnsafeNode* n);
virtual ~UnsafeNode();
UnsafeNode* Next();
void* Data();
};
template <class Type>
class SafeNode : private UnsafeNode {
public:
SafeNode(Type* d, SafeNode* n) : UnsafeNode(d, n) {}
virtual ~SafeNode() { delete (Type*)Data(); }
SafeNode* Next() { return (SafeNode*)UnsafeNode::Next(); }
Type* Data() { return (Type*)UnsafeNode::Data(); }
.
, C++.
Next() Data()
, ;
, .
,
. ,
, .
, . ,
.
Next() Data(), ,
.
:
61
.
. ;
.
UnsafeNode.
SafeNode UnsafeNode SafeNode.
SafeNode SafeNode ! .
UnsafeNode UnsafeNode, SafeNode.
.
// SafeList.h
class UnsafeNode; //
template <class Type>
class SafeList { // UnsafeNode
private:
UnsafeNode* head;
public:
SafeList() : head(NULL) {}
~SafeList();
UnsafeNode* Cursor(); //
Type* Next(UnsafeNode*&); //
void DeleteAt(UnsafeNode*&); //
void InsertFirst(Type*); //
void InsertBefore(UnsafeNode*&); //
void InsertAfter(UnsafeNode*&); //
};
// SafeList.cpp
class UnsafeNode { // ListNode
private:
UnsafeNode* next;
void* data;
public:
UnsafeNode(void* d, UnsafeNode* n);
virtual ~UnsafeNode();
UnsafeNode* Next();
void* Data();
};
SafeList , . (
InsertFirst) , . ,
, ( ).
, .
, ,
SafeList. , ,
. : UnsafeNode ,
. .
, <>,
, .
, .
4
, .
, .
, ,
. ,
, . ,
,
. :
if ( ) {
;
}
else {
- ;
}
, . ,
, .
,
.
. ,
.
ANSI
: ANSI ,
C++, . ,
? , ,
. ,
. , .
:
C++. :
. : , .
.
, ,
, .
, .
throw. ,
Gotcha.
enum Gotcha { kTooLow, kTooHigh };
void fn(int x) throw(Gotcha) {
64
if (x < 0)
throw kTooLow; //
if (x > 1000)
throw kTooHigh; //
// -
}
. : ,
, .
, ,
.
Gotcha. , ,
,
. .
.
void Fn() throw(int); //
// - .cpp
void Fn() throw(int) {
//
}
,
.
, .
, .
void fn(); //
,
, .
, ,
.
void fn() throw(); //
,
, .
void fn() throw(int, Exception_Struct, char*);
,
, , .
void fn() throw;
. ,
( !)
. :
65
void f1(int) throw();
void f1(int) throw(Exception); // !
2 (, , ) (overloading)
(overriding).
, ,
( - , ;
). .
class Foo {
public:
virtual Fn() throw(int);
};
class Bar : public Foo {
public:
virtual Fn() throw(char*); // !
};
, . , Foo*,
int, , r,
.
: .
,
.
,
. .
unexpected(). terminate(),
, , .
except.h :
typedef void (*unexpected_function)();
unexpected_function set_unexpected(unexpected_function excpected_func);
typedef... . set_unexpected()
.
set_unexpected() .
, .
, .
unexpected_function my_handler(void) {
//
}
{ //
unexpected_function old_handler = set_unexpected(my_handler);
//
set_unexpected(old_handler);
}
- ,
return
. ,
, .
66
, try
catch, (handlers).
try {
// ,
}
catch (Exception_Type t) {
// Exception_Type
}
catch (...) {
//
}
, ( ) ,
. , try-,
,
, .
; ,
.
.
catch ,
, .
try- ,
.
, ,
.
( ): goto
. ,
.
catch(int exception) {
// -,
throw(Help!); // char*
}
,
terminate(). , ? terminate()
abort(),
.
set_terminate(). except.h :
typedef void (*terminate_function)();
termination_function set_terminate(terminate_function t_func);
typedef... .
set_terminate() , abort()
terminate(). set_terminate() ,
set_terminate().
67
. ,
.
, try/catch ,
,
.
{
try {
try {
try {
//
}
catch(...) {
}
}
catch(...) {
}
}
catch(...) {
}
}
,
.
!
, throw. ,
, .
,
Ctrl, , ,
. ,
, ; .
(unwinding the stack).
throw catch.
void fn() throw(int) {
Foo aFoo;
// - !
throw(bad_news);
}
,
aFoo. try- .
{
try {
Bar b;
fn(); //
}
68
catch(int exception) {
// , , b
}
}
, ,
try-. ,
. ,
.
,
try-, . , ,
. ,
.
( new) .
. ,
,
.
class TempFoo {
private:
Foo* f;
public:
TempFoo(Foo* aFoo) : f(aFoo) {}
~TempFoo() { delete f; }
};
try {
TempFoo tf(new Foo);
// ..
}
catch(...) {
// Foo tf
}
:
class Foo {...}
class Bar : public Foo {
private:
A a;
B b;
public:
Bar();
};
Bar::Bar()
{
X x;
throw(bad_news);
Y y;
}
69
,
( ),
. r . ,
(Foo) ( b) ,
.
x. , .
Bar ,
.
, b . Foo
, b, Bar .
, .
,
, .
, .
, .
.
try/catch ,
.
.
, ,
. ,
, - (
). , :
. , ,
.
- ,
,
.
99% ,
. ,
, , ,
, .
, .
throw catch,
, . ,
. -
,
throw:
f()
{
if (pool->Allocate(size) == NULL)
//
}
2
?
++ .
( ) ++ ,
.
, ,
.
,
. ,
.
5
, ->,
. :
class Foo {
public:
void MemberOfFoo();
};
Foo* aFoo = new Foo;
aFoo->MemberOfFoo();
, -> ,
aFoo. C++ ,
, . ->
, ( MemberOfFoo()).
(Foo) ->. ,
;
->.
-> C++, ,
( .), . 2,
,
.
C++ , int, double .
. , int ,
Integer, :
class Integer {
private:
int value;
public:
Integer() : value(0) {}
Integer(int v) : value(v) {}
operator int() { return value; }
Integer operator+(Integer i) { return Integer(value + i.value); }
Integer operator+=(Integer i) { value += i.value; return *this; }
// ..
};
int f(int);
f(Integer(17)); // int()
74
Integer , int
Integer. ,
char* ( atoi()) . Integer
int (, int),
int() .
. ! int
Integer. , int.
.
? , C++ (
-) , *- ,
( ; , !).
, . , .
class PFoo {
private:
Foo* foo;
public:
PFoo() : foo(NULL) {}
PFoo(Foo* f) : foo(f) {}
operator Foo*() { return foo; }
PFoo operator+(ptr_diff offset) { return PFoo(foo + offset); }
PFoo operator+=(ptr_diff offset) { foo += offset; return *this; }
ptr_diff operator-(PFoo pf) { return foo - pf.foo; }
// ..
};
! , Foo*!
. , , ,
ptr_diff .
, Foo,
PFoo Foo*... ? .
.
PFoo pf(new Foo*);
pf->MemberOfFoo(); //
((Foo*)pf)->MemberOfFoo(); // , !
Foo*() PFoo ,
Foo*. ,
, -> .
, ,
.
, , ?
1. ,
. , ,
. PFoo
Foo .
2. , (, size_t
ptr_diff). ,
.
3.
->. .
75
.
, ptr_diff.
->
, -> .
, 2, PFoo ->.
. f()
, ,
, Foo*() .
class PFoo {
private:
Foo* foo;
public:
PFoo() : foo(NULL) {}
PFoo(Foo* f) : foo(f) {}
operator Foo*() { return foo; }
Foo* operator->() { return foo; }
};
void f(Foo*);
PFoo pf(new Foo);
f(pf); // operator Foo*()
pf->MemberOfFoo(); // operator->()
, pf->MemberOfFoo(), . ->
, ->.
, pf ,
->. ,
.
, ,
. - (, int),
.
, -, .
. ,
, , :
PFoo operator->() { return *this; }
->
. C++ .
, -, ,
Foo*: , ->
, Foo*
.
.
template <class Type>
class SP {
private:
Type* pointer;
public:
76
SP() : pointer(NULL) {}
SP(Type* p) : pointer(p) {}
operator Type*() { return pointer; }
Type* operator->() { return pointer; }
};
void f(Foo*);
Ptr<Foo> pf(new Foo);
f(pf); // operator Type*()
pf->MemberOfFoo(); // operator->()
, Foo.
.
,
.
C++ ,
:
1. P<Foo>, <r>? . .
2. <r> operator P<Foo>()? . .
3. <r> ,
- P<Foo>? ! operator Bar*()
<r> Bar*, Foo*.
Ptr<Foo>pf2(Foo*(pb.operator Bar*())),
Bar* Foo* ,
.
, ,
.
(inline) operator Bar*() P<Foo>(Foo*)
, ; (
, ) ,
. : ,
, .
,
. ,
.
class PVoid { // void*
protected:
void* addr;
public:
PVoid() : addr(NULL) {}
PVoid(void* a) : addr(a) {}
operator void*() { return addr; }
};
class Foo : public PVoid {
public:
PFoo() : PVoid() {}
PFoo(Foo* p) : PVoid(p) {}
operator Foo*() { return (Foo*)addr; }
Foo* operator->() { return (Foo*)addr; }
77
};
class Pbar : public PFoo {
public:
PBar() : PFoo() {}
PBar(Bar* p) : PFoo(p) {}
operator Bar*() { return (Bar*)addr; }
Bar* operator->() { return (Bar*)addr; }
};
pBar pb(new Bar);
pFoo pf(pb); // , PBar PFoo
pf->MemberOfFoo(); // PFoo::operator->
, / (
) , r::operator->()
PFoo::operator->(). , ,
Ptr.
,
/ . ,
++ --.
template <class Type>
class Ptr {
private:
Type* pointer;
public:
Ptr() : pointer(NULL) {}
Ptr(Type* p) : pointer(p) {}
operator Type*() { return pointer; }
ptr_diff operator-(Ptr<Type> p) { return pointer p.pointer; }
ptr_diff operator-(void* v) { return ((void*)pointer) v; }
Ptr<Type> operator-(long index) { return Ptr<Type>(pointer index); }
Ptr<Type> operator-=(long index) { pointer -= index; return *this; }
Ptr<Type> operator+(long index) { return Ptr<Type>(pointer + index); }
Ptr<Type> operator+=(long index) { pointer += index; return *this; }
};
, ptr_diff .
, , .
, . : C++,
, , .
,
.
-
, , , .
,
, .
,
.
78
?
, , ,
.
*-;
. C++
, .
template <class Type>
class Ptr {
private:
Type* pointer;
public:
Ptr() : pointer(NULL) {}
Ptr(Type* p) : pointer(p) {}
operator Type*() { return pointer; }
Type* operator->() { return pointer; }
};
, ->
. ,
.
. , .
, ,
. , ,
, .
NULL
:
template <class Type>
class SPN {
private:
Type* pointer;
public:
SPN() : pointer(NULL) {}
SPN(Type* p) : pointer(p) {}
operator Type*() { return pointer; }
Type* operator->()
{
if (pointer == NULL) {
cerr << Dereferencing NULL! << endl;
pointer = new Type;
}
return pointer;
}
#indef
, ,
if- #ifdef,
. ->
.
.
:
template <class Type>
class Ptr {
private:
Type* pointer;
public:
enum ErrorType { DereferenceNil };
Ptr() : pointer(NULL) {}
Ptr(Type* p) : pointer(p) {}
operator Type*() { return pointer; }
Type* operator->() throw(ErrorType)
{
if (pointer == NULL) throw DereferenceNil;
return pointer;
}
};
( ErrorType , ;
.)
. ,
.
,
(screamer). , -
NULL.
template <class Type>
class AHHH {
private:
Type* pointer;
static type* screamer;
public:
AHHH() : pointer(NULL) {}
AHHH(Type* p) : pointer(p) {}
Operator Type*() { return pointer; }
Type* operator->()
{
if (p == NULL) return screamer;
return pointer;
80
}
};
? . , screamer
Type* , ( )
rr .
,
.
,
. operator
Type*() operator->(),
. ,
.
(out-
of-line) .
template <class Type>
class PTracer {
private:
Type* pointer;
public:
PTracer() : pointer(NULL) {}
PTracer(Type* p) : pointer(p) {}
operator Type*();
Type* operator->();
};
template <class Type>
#ifdef DEBUGGING
inline
#endif
PTracer<Type>::operator Type*()
{
return pointer; //
}
template <class Type>
#ifdef DEBUGGING
inline
#endif
Type* PTracer<Type>::operator->()
{
return pointer; //
}
,
.
-> cout
cerr, .
81
Type* ->
.
template <class Type>
class SPCS {
private:
Type* pointer;
static int conversions;
static int members;
public:
SPCS() : pointer(NULL) {}
SPCS(Type* p) : pointer(p) {}
operator Type*() { conversions++; return pointer; }
Type* operator->() { members++; return pointer; }
int Conversions() { return conversions; }
int Members() { return members; }
};
- . Foo.cpp:
// Foo.cpp
int Ptr<Foo>::conversions = 0;
int Ptr<Foo>::members = 0;
, #ifdef,
.
. ,
(master pointers),
, . ,
( ),
() .
. ,
, .
, , Counter.
class Counter {
protected:
Counter() : conversions(0), members(0) {}
Counter(const Counter&) : conversions(0), members(0) {}
Counter& operator=(const Counter&) { return *this; }
public:
int conversions;
int members;
int Conversions() { return conversions; }
int Members() { return members; }
};
template <class Type>
class SPOP {
private:
Type* pointer;
82
public:
SPOS() : pointer(NULL) {}
SPOP(Type* f) : pointer(f) {}
operator Type*() { pointer->conversions++; return pointer; }
Type* operator->() { pointer->members++; return pointer; }
};
,
.
, ,
. , ReadObject()
,
pointer. ,
.
typedef unsigned long DiskAddress; //
template <class Type>
class CP {
private:
DiskAddress record_number;
Type* pointer;
void ReadObject(); //
public:
CP(DiskAddress da) : pointer(NULL), record_number(da) {}
CP(Type* f) : pointer(f), record_number(f->RecordNumber()) {}
operator Type*()
{
if (pointer == NULL) this->ReadObject();
return pointer;
}
Type* operator->()
{
if (pointer == NULL) this->ReadObject();
return pointer;
}
};
,
, . ,
, ,
, ,
. ,
, ,
.
.
:
1. .
2. , new,
.
83
,
. ( ), 31
. , 32 .
, ,
, , , .
:
,
. C++,
, ,
.
6
. ,
. ,
? (
)? ?
?
? .
. ,
, ( ,
NULL). , ,
(master pointers).
, ,
.
C++. ,
:
1. .
2. .
3. .
4. operator= ,
, .
, :
5. .
6. (factory functions).
.
, , :
template <class Type>
class MP {
private:
Type* t;
public:
86
MP(); //
MP(const MP<Type>&); //
~MP(); //
MP<Type>& operator=(const MP<Type>&); // ,
//
Type* operator->() const;
};
,
.
template <class Type>
class MP {
private:
Type* t;
public:
MP() : t(NULL) {}
MP(Type* pointer) : t(pointer) {}
~MP() { delete t; }
// ..
};
Foo* foo = new Foo;
MP<Foo> mp1(foo);
MP<Foo> mp2(foo); // !
! mp1 , foo.
mp2 . - ?
. : ?
, : - - ,
.
- : , .
: .
class Foo {
friend class MP<Foo>;
protected:
Foo(); // MP<Foo>
public:
//
};
template <class Type>
class MP {
private:
Type* t;
public:
MP() : t(new Type) {}
// ..
};
Aa, . .
, Foo
87
. Foo,
MP<Foo>. , ,
, .
Foo , :
1. ,
Foo MPFoo. Foo
MPFoo Foo.
2.
,
.
:
class Foo {
friend class MP<Foo>;
protected:
Foo(); //
public:
Initialized(int, char*);
//
};
MP<Foo> mpf;
mpf->Initialize(17, Hello); //
,
. ,
.
.
: .
template <class Type>
class MP {
private:
Type* t;
public:
~MP() { delete t; }
};
! ...
MP<Foo> mpf1; // Foo,
MP<Foo> mpf2 = mpf1; // !
,
MP<Foo> mpf2(mpfl);.
C++ , ,
Foo. , , -
.
.
template <class Type>
class MP {
88
private:
Type* t;
public:
MP(); //
MP(const MP<Type>& mp) : t(*(mp.t)) {} //
};
,
. , . ,
, .
.
template <class Type>
class MP {
private:
Type* t;
MP(const MP<Type>&) : t(NULL) {} //
public:
MP();
};
:
void f(MP<Foo>);
MP<Foo> mpf;
f(mpf); //
,
.
! - ?!
MP<Foo> mpf1;
MP<Foo> mpf2;
mpf2 = mpf1; // , ...
. -, ,
mpf2, . ,
. -, =, ,
, t, ,
, .
= , , ,
.
template <class Type>
class MP {
private:
Type* t;
public:
MP(); //
MP<Type>& operator=(const MP<Type>& mp)
{
if (&mp != this) {
delete t;
t = new Type(*(mp.t));
89
}
return *this;
}
};
, , =
.
.
. , ,
:
1. .
2. ,
.
,
, . :
( ).
template <class Type>
class MP {
private:
Type* t;
public:
MP(); //
MP(const MP<Type>&); //
~MP(); //
MP<Type>& operator=(const MP<Type>&);
Type* operator->() const;
};
template <class Type>
inline MP<Type>::MP() : t(new Type)
{}
template <class Type>
inline MP<Type>::MP(const MP<Type>& mp) : t(new Type(*(mp.t)))
{}
template <class Type>
inline MP<Type>::~MP()
{
delete t;
}
template <class Type>
inline MP<Type>& MP<Type>::operator=(const MP<Type>& mp)
{
if (this != &mp) {
delete t;
t = new Type(*(mp.t));
}
return *this;
90
}
template <class Type>
inline Type* MP<Type>::operator->() const
{
return t;
}
C++
, .
(handles) C++.
, Macintosh Windows.
, C++ .
,
. . ,
, :
template <class Type>
class H {
private:
MP<Type>& ptr; //
public:
H() : ptr(*(new MP<Type>)) {} // .
H(MP<Type>& mp) : ptr(mp) {}
MP<Type>& operator->() const { return ptr; }
};
. ,
, . ,
ptr. =
, .
-> , : ->
; ->
Type* .
,
, . ,
, ?
,
?
.
?
,
.
, .
,
.
.
class CountedStuff {
private:
91
static int current;
public:
CountedStuff() { current++; }
CountedStuff(const CuntedStuff&) { current++; }
CountedStuff& operator=(const CountedStuff&)
{} //
~CountedStuff() { current--; }
};
, ,
, .
, . , ?
, , .
.
template <class Type>
class CMP {
private:
static int current;
Type* ptr;
public:
CMP() : ptr(new Type) { current++; }
CMP(const CMP<Type>& cmp) : ptr(new Type(*(mp.t))) { current++; }
CMP<Type>& operator=(const CMP<Type>& cmp)
{
if (this != &cmp) {
delete ptr;
ptr = new Type(*(cmp.ptr));
}
return *this;
}
~CMP() { delete ptr; current--; }
Type* operator->() const { return ptr; }
Static int Current() { return current; }
};
.
. ,
.
,
(,
, current
).
, C++,
: ,
, . ,
.
* , .
14 ,
.
92
, , (,
, ).
operator->() .
template <class Type>
class ROMP {
private:
Type* t;
public:
ROMP(); //
ROMP(const ROMP<Type>&); //
~ROMP(); //
ROMP<Type>& operator=(const ROMP<Type>&);
const Type* operator->() const;
};
, . ,
,
, .
/
,
. , .
->,
Foo*, const Foo*. ,
, ->
. ,
.
.
, .
. ,
, .
,
. , ( ,
),
.
7
, .
,
*-, ,
.
.
, , ,
.
,
.
.
.
,
.
, ; ;
:
.
, (
) (smarter pointers).
, ->. -> :
, .
class Foo {
// ,
};
Ptr<Foo> pf(new Foo);
. ,
Foo. . .
, .
class Foo {
friend class Pfoo;
protected:
Foo();
public:
94
void DoSomething();
void DoSomethingElse();
};
class PFoo {
private:
Foo* foo;
public:
PFoo() : foo(new Foo) {}
PFoo(const PFoo& pf) : foo(new Foo(*(pf.foo))) {}
~PFoo() { delete Foo; }
PFoo& operator=(const PFoo& pf)
{
if (this != &pf) {
delete foo;
foo = new Foo(*(pf.foo));
}
return *this;
}
void DoSomething() { foo->DoSomething(); }
void DoSomethingElse() { foo->DoSomethingElse(); }
};
: /
.
->,
, -
. , ,
(interface pointers).
, . ,
Foo .h PFoo.
, ,
.
class Foo1; // , Foo
class PFoo1 {
private:
Foo1* foo;
public:
PFoo1();
PFoo1(const PFoo1& pf);
~PFoo();
PFoo1& operator=(const PFoo1& pf);
void DoSomething();
void DoSomethingElse();
};
class Foo1 {
friend class PFoo1;
protected:
Foo1();
95
public:
void DoSomething();
void DoSomethingElse();
};
PFoo1::~PFoo()
{
delete foo;
}
void PFoo1::DoSomething()
{
foo->DoSomething();
}
void PFoo1::DoSomethingElse()
{
foo->DoSomethingElse();
}
Foo1::Foo1()
{
}
void Foo1::DoSomething()
{
cout << Foo::DoSomething() << endl;
}
void Foo1::DoSomethingElse()
{
cout << Foo::DoSomethingElse() << endl;
}
96
, ? Foo .
. ,
Foo -6 . ,
, class Foo;.
(noninline)
.
. :
->
.h
. ,
.
,
. ,
, ;
, , -
, .
( )
, . -
, . ,
, .
class View { //
protected:
// ,
public:
//
//
//
//
//
// ( ?)
//
};
.
; ,
. ,
,
.
, .
.
, .
, ?
,
, .
,
.
.
97
,
? , .
,
.
class ViewEvents {
private:
View* view;
public:
// ,
};
class ViewDrawing {
private:
View* view;
public:
// ,
};
// ..
View - .
: ,
; .
,
, (facets).
(, Component Object Model) Microsoft,
. , Quasar Knowledge Systems,
SmallTalk (suites).
, -
,
.
,
. , .
, .
, C++
.
class View {
public:
operator ViewEvents() { return new ViewEvents(this); }
operator ViewDrawing() { return new ViewDrawing(this); }
};
:
ViewEvents ve(aView);
,
, . ,
,
.
, , NULL -
98
. , OLE
Microsoft, QueryInterface, .
,
.
:
class ViewEvents {
private:
View* view;
public:
operator ViewDrawing() { return ViewDrawing(*view); }
// ..
};
class ViewEvents {
friend class ViewGemstone;
private:
View* view;
ViewEvents(View* v) : view(v) {}
public:
bool operator!() { return view == NULL; }
operator ViewGemstone();
};
class ViewDrawing {
friend class ViewGemstone;
private:
View* view;
ViewDrawing(View* v) : view(v) {}
99
public:
bool operator!() { return view == NULL; }
operator ViewGemstone();
};
, , ; ,
, , . ,
, .
,
.
, ,
. , -
ViewGemstone . ,
.
; .
, ( ).
.
.
, C++ .
,
.
// Pointee.h
class Pointee;
class Facet {
friend class PointeeGemstone;
private:
Pointee* pointee;
Facet(Pointee* p) : pointee(p) {}
public:
void Fn1();
int Fn2();
void Fn17();
};
class PointeeGemstone {
private:
Pointee* pointee;
public:
PointeeGemstone(Pointee* p) : pointee(p) {}
Operator Facet();
};
// Pointee.cpp
class Pointee {
public:
void Fn1();
100
int Fn2();
void Fn3();
char Fn4();
// ..
void Fn17();
};
, .
, ,
.
.
. Bar,
Bar.
// Pointee.h
class BarFacet {
private:
Bar* bar;
public:
BarFacet(Bar* b) : bar(b) {}
// Bar
};
class PointeeGemstone {
private:
Pointee* p;
public:
operator BarFacet();
// ..
};
// Pointee.cpp
class Pointee {
friend class PointeeGemstone;
private:
Bar bar; // Pointee
public:
// ..
};
PointeeGemstone::operator BarFacet()
{
return BarFacet(&p->Bar); //
}
, C++.
, , ,
. ,
101
, BarFacet,
, .
.
// Pointee.h
class FooFacet {
private:
Foo* foo;
public:
FooFacet(Foo* f) : foo(f) {}
// foo
};
class PointeeGemstone {
private:
Pointee* p;
public:
operator FooFacet();
// ..
};
// Pointee.cpp
class Pointee : public Foo {
friend class PointeeGemstone;
public:
// ..
};
PointeeGemstone::operator FooFacet()
{
return FooFacet(p); // p Foo*
}
-,
Foo , ,
, , . ,
FooFacet,
.
( ,
) .
. -, ,
, .
// Pointee.h
class BarFacet {
private:
Bar* bar;
102
public:
BarFacet(Bar* b) : bar(b) {}
// Bar
};
class PointeeGemstone {
private:
Pointee* p;
public:
operator BarFacet();
// ..
};
// Pointee.cpp
class Pointee {
friend class PointeeGemstone;
private:
Bar* bar; //
public:
// ..
};
PointeeGemstone::operator BarFacet()
{
return BarFacet(&p->Bar);
}
, -.
, ,
. ,
; ,
; , ; ,
.
C++ 1995 .
View,
? , ,
? .
?
, , ,
. , .h
..
.
.
(recomposed) .
,
.
103
,
. , ,
, :
, ?
++- !.
class ViewEvents {
private:
View* view;
public:
ViewEvents(View* v) : view(v) {}
bool operator!() { return view == NULL; }
// ..
};
//
ViewEvents ve(aViewGemstone);
if (!ve) {
cerr << ! << endl;
throw interface_error;
}
, aViewGemstone , ,
operator ViewEvents(). ViewEvents
ve(aViewGenistone) : operator
ViewEvents(), , ve
ViewEvents. , ,
ViewEvents view, NULL. !
. ,
- .
Void ViewEvents::DoSomething()
{
if (!*this) // if (view == NULL)
//
view->DoSomething();
}
C++ , , , .
.
, ,
.
, .
, .
,
, .
C++. , -
C++ .
=>b , , B;
b .
C++ , ,
Microsoft:
104
1. . =>b, b=>. :
, ,
.
2. . =>b, => b=>c2, 2 ; ,
,
. .
3. . , . ,
! false .
, . ,
.
,
. , ,
, . .
; ,
.
.
, ,
.
class BarFacet {
private:
Bar* bar;
PointeeGemstone* gemstone;
public:
BarFacet(Bar* b, PointeeGemstone* agg) : bar(b), gemstone(agg) {}
operator PointeeGemstone() { return *gemstone; }
// Bar
};
; . ,
. , BarFacet
, ;
.
.
:
class Foo {
private:
Blob* blob;
Bar* bar;
};
class Bar {
private:
Blob* another_blob;
};
105
Foo lob, ,
. Bar, Bar Blob,
, Bar.
(
) . ,
:
class Blob { ... };
class Foo : public Blob { ... };
class Bar : public Foo, public Blob { ... };
. Bar* Blob* ,
Blob : Bar ,
Foo? , .
? ,
: .
( ,
).
,
.
C++ , ,
.
.
. (
, ) ,
. .
, :
? , !
true, . ,
.
.
.
.
(, ->)
. ,
.
,
. , ,
-> , .
.
.
. ,
-> .
, .
106
(malleable type) - ,
. , C++
. ,
.
Pointee*. o ,
, , Pointee, - ,
Pointee?
// Foo.h
class Foo {
protected:
Foo();
public:
// Foo
};
class Pfoo { //
private:
Foo* foo;
public:
PFoo();
Foo* operator->() const { return foo; }
// ,
};
// Foo.cpp
class DerivedFromFoo : public Foo {
private:
//
public:
DerivedFromFoo(); // , .cpp
// Foo
};
! Foo
, . ! , Foo
, ! PFoo ;
Foo DerivedFromFoo.
3 , , ( ,
, Foo, , Foo).
, .
107
,
?
// Foo.cpp
class DeirvedFromFoo : public Foo { ... };
class AlsoDerivedFromFoo : public Foo { ... };
PFoo::PFoo(bool x) : foo(x ? new DerivedFromFoo : new AlsoDerivedFromFoo) {}
,
, . ,
.
.
class Foo;
class PFoo {
private:
Foo* foo;
public:
PFoo();
void DoSomething(bool x);
//
};
void PFoo::DoSomething(bool x)
{
if (x) {
delete foo;
foo = new DerivedFromFoo;
}
Foo->DoSomething();
}
:
. ,
(, ).
, -
, .
.
; ,
- . , , ,
(proxy). ,
.
,
.
,
. , -
, , , .
108
- ++
. .
? -> .
; , , ,
. . ,
. ,
, .
, .
?
class Pointee; //
class Interface {
private:
Pointee* pointee;
public:
//
};
pointee. , ,
, . 3
, .
:
( (outline) )
.
.
C++, (functor).
, .
, ,
, ,
, . -,
,
.
, , (closure)
.
procedure p(n: integer);
var
procedure fn;
begin
do_something(n);
end;
begin
callback(@fn);
end;
llbackfn .
fn. fn callbackfn ,
. fn n
llbackfn.
(callback),
- , .
, , .
109
class Fn {
private:
int number;
public:
f(int n) : number(n) {}
void operator() () { do_something(number); }
};
void callbackfn(Fn);
void p(int n)
{
callbackfn(Fn(n));
}
. callbackfn(Fn(n))
Fn. ,
, Fn. fn();
,
operator() Fn. , do_something
. ?
operator() .
, .
() . ,
operator() .
class Fn {
private:
int number;
public:
f(int n) : number(n) {}
void operator() () { do_something(number); }
void operator() (char* s)
{
do_something(number);
cout << - << s << endl;
}
};
void callbackfn(Fn);
void p(int n)
{
callbackfn(Fn(n));
}
110
,
().
class Fn {
private:
int number;
public:
f(int n) : number(n) {}
void do_something() () { ::do_something(number); }
void do_something() (char* s)
{
do_something(number);
cout << - << s << endl;
}
};
void callbackfn(Fn);
void p(int n)
{
callbackfn(Fn(n));
}
, .
() , .
, ,
(); .
8
,
- ( ,
) , - .
,
, , . .
, - SmallTalk
C++,
. ++-,
C++
.
,
,
. [], .
, -
, .
,
.
[]
[] . , C++
.
[] ,
, ,
( ).
class ArrayOfFoo {
private:
int entries;
Foo** contents; // Foo*
static Foo* dummy; // ,
public:
ArrayOfFoo() : entries(0), contents(NULL) {};
ArrayOfFoo(int size) : entries(size), contents(new Foo*[size]) {};
~ArrayOfFoo() { delete contents; }
Foo*& operator[](int index)
112
{
return (index < 0 || index >= entries) ? dummy : contents[index];
}
};
// - .cpp
Foo* ArrayOfFoo::dummy = NULL;
[] Foo*&, Foo.
, ,
, .
Foo* foo = array[17];
array[29] = foo; //
[] Foo*, ,
. Foo*&,
, . ,
, ,
. ,
(, #ifdef ),
.
C/C++, #ifdef.
,
, .
[]
[] , . []
,
. ,
String,
.
class Association {
//
public:
const String& operator[](const String& key);
};
//
String str = assotiation[another_string];
,
, :
String str = assotiation.LookUp(another_string);
[] .
, ,
[] :
class WontWork {
public:
Foo& operator[](int x, int y); // --
113
};
, -
.
, .
, , .
struct Index {
int x;
int y;
Index(int ex, int why) : x(ex), y(why) {}
bool operator==(const Index& i) { return x == i.x && y == i.y; }
};
class WorksFine {
public:
Foo& operator[](Index i);
};
array[Index(17, 29)].MemberOfFoo(); //
Index . ==
. Index(17,29) ,
. ? , !
[]
[] ,
. , int,
char*, int atoi(). ,
.
class StringArray {
public:
const String& operator[](int index);
int operator[](const String&);
};
[] :
. :
. (,
, ),
.
[]
[], ,
.
, .
, 3.
114
. Foo*
, -
.
association[String(Hello)] = String(Good looking);
, (lvalue),
=.
, -
, []. ,
[], ,
. ( ),
( ).
. ,
. ,
256 ,
100010001000.
, 1000. ,
,
: , , - , .
, .
,
, ?
. Index .
class SparseArray {
private:
struct Node {
Index index; //
Foo* content; //
Node* next; //
Node(Index i, Foo* f, Node* n) : index(i), content(f), next(n) {};
};
Node* cells; //
public:
SparseArray() : cells(NULL) {}
Foo* operator[](Index i);
};
. ,
. , NULL
NULL. ,
? ,
operator[], (lvalue),
= .
array[Index(31, 37)] = foo; //
,
rr . ,
, , .
[] ,
? , , .
, . operator[]
, :
1. .
2.
.
, (cursor).
operator[]:
class ArrayCursor;
class SparseArray {
friend class ArrayCursor;
private:
struct Node {
Index index;
Foo* content;
Node* next;
Node(Index i, Foo* c, Node* n) : index(i), content(c), next(n) {};
};
Node* cells;
public:
SparseArray() : cells(NULL) {}
ArrayCursor operator[](Index i);
};
class ArrayCursor {
friend class SparseArray;
private:
SparseArray& array; // -
Index index; // ,
SparseArray::Node* node; // , NULL
// ,
// SparseArray. ,
// ,
// .
116
ArrayCursor(SparseArray& arr, Index i)
: array(arr), index(i), node(NULL) {}
ArrayCursor(SparseArray& arr, SparseArray::Node* n)
: array(arr), node(n), index(n->index) {}
public:
// =
// .
ArrayCursor& operator=(Foo* foo);
};
ArrayCursor SparseArray::operator[](Index i)
{
SparseArray::Node* n = cells;
while (n != NULL)
if (n->index = i)
return ArrayCursor(*this, n); //
else
n = n->next;
return ArrayCursor(*this, i); //
}
! ?
, SparseArray::operator[]() ArrayCursor::operator=(). SparseArray::
operator[]() ArrayCursor , (
ArrayCursor , ). ArrayCursor::operator=(Foo*)
: , ,
. (?):
= , ,
. ,
.
array[Index(17, 29)] = new Foo; //
array[Index(17, 29)] = new Foo; //
, ? . .
->
. -, []
, , ArrayCursor, Foo* Foo*&.
, Foo*()
ArrayCursor Foo*. , []
->; operator->()!
117
class ArrayCursor {
friend class SparseArray;
private:
SparseArray& array;
Index index;
SparseArray::Node* node;
ArrayCursor(SparseArray& arr, Index i)
: array(arr), index(i), node(NULL) {}
ArrayCursor(SparseArray& arr, SparseArray::Node* n)
: array(arr), node(n), index(n->index) {}
public:
ArrayCursor& operator=(Foo* foo);
operator Foo*() { return node != NULL ? node->content : NULL; };
Foo* operator->()
{
if (node = NULL)
//
else
return node->contents;
}
};
, .
. ,
.
-
ArrayCursor. ,
Foo, operator Foo*() ->,
Foo . ? .
. , -
, . ,
. =
, . ,
,
->.
.
( , ArrayCursor SparseArray).
C++. ,
.
, . ,
? for :
for (int i = 0; i < ... ?
. ,
, 1 000 000 000
118
- ? , , RISC-
, .
, .
, ; ,
.
(iterators) , !
. -
C++ ,
.
, .
class Collection {
public:
class Iterator {
public:
bool More();
Foo* Next();
};
Collection::Iterator* Iterate(); //
};
Collection::Iterator* iter = collection->Iterator();
while (iter.More())
f(iter.Next());
, ;
. r() true,
, false . Next()
.
, ,
, .
template <class Type>
class Iterator { //
public:
virtual bool More() = 0;
virtual Type* Next() = 0;
};
, -
,
. , ,
(, ),
, .
,
. , -
. ,
.
, .
, ,
.
119
,
. :
class Iterator;
class Collection {
public:
Iterator* Iterate(); //
bool More(Iterator*);
Foo* Next(Iterator*);
};
Iterator* iter = collection->Iterate();
while (collection->More(iter))
f(collection->Next(iter));
,
.
?
,
:
,
.
. Iterator ,
.
,
. .
,
.
.
,
.
,
.
. ,
++, .
.
, ,
, .
class Collection { ... };
class CollectionIterator {
private:
Collection* coll;
public:
CollectionIterator(Collection* coll);
bool More();
Foo* Next();
};
120
CollectionIterator iter(collection); //
while (iter.More())
f(iter.Next());
, :
, Collection, ,
CollectionIterator.
.
, ,
.
,
.
.
, , : , ,
, . ,
.
void*
, ,
void*. - typedef,
void* .
typedef void* AprilInParis;
class Collection {
public:
AprilInParis Iterate(); // void*
bool More(AprilInParis&);
Foo* Next(AprilInParis&);
};
, - , void*,
Collection void* . ,
, void*
. , ,
, .
.
Next()
void* -
. , Next(),
, - .
, .
, ,
.
, . ,
- .
121
, .
, Rewind().
, .
, , ,
.
class Collection {
public:
class Iterator {
public:
Iterator(Key* low, Key* high);
// ..
};
// ..
};
low high
. More() Next() ,
. X,
X (< <=).
Previous() ,
.
Current(), , Next() .
, , Next()
*-, , , .
, .
: Next()
, .
; .
.
,
.
, Next() , ,
Next().
. ,
, .
// SparseArray.h
class ArrayCursor;
class SparseArray {
friend class ArrayCursor;
private:
struct Node {
Index index;
Foo* content;
122
Node* next;
Node(Index i, Foo* c, Node* n) : index(i), content(c), next(n) {}
};
Node* cells;
public:
class Iterator {
private:
Node* next;
public:
Iterator(Node* first) : next(first) {}
bool More() { return next != NULL; ]
Foo* Next(Index& index)
{
Foo* object = next->content;
index = next->index;
next = next->next;
return object;
}
};
Iterator* NonEmpty() { return new SparseArray::Iterator(cells); }
SparseArray() : cells(NULL) {}
ArrayCursor operator[](Index i);
};
class ArrayCursor {
friend class SparseArray;
private:
SparseArray& array;
Index index;
SparseArray::Node* node;
ArrayCursor(SparseArray& arr, Index i)
: array(arr), index(i), node(NULL) {}
ArrayCursor(SparseArray& arr, SparseArray::Node* n)
: array(arr), node(n), index(n->index) {}
public:
ArrayCursor& operator=(Foo* foo);
operator Foo*() { return node != NULL ? node->content : NULL; }
Foo* operator->()
{
if (node == NULL)
throw nil_error;
else
return node->current;
}
};
,
++, , .
, :
123
SparseArray::Iterator, ,
NonEmpty() (
, 3).
, ,
.
.
Next() , ,
. , ,
Next().
[],
[] .
; -
. Next() Index&,
, -
.
. [], ++
.
,
.
.
template <class Element>
class Set {
public:
Set(); //
Set(const Set<Element>&); //
Set(Element*); //
// (, )
// ( |=, &=, -=, <, <=)
Set<Element> operator|(const Set<Element>&) const; //
//
Set<Element> operator&(const Set<Element>&) const; //
Set<Element> operator-(const Set<Element>-) const; //
//
bool operator>(const Set<Element>&) const; // , this
//
bool operator>=(const Set<Element>&) const; // , this
//
bool operator==(const Set<Element>&) const; // ,
//
// (, *)
// ( |=, -=)
Set<Element> operator|(Element*); // this
Set<Element> operator-(Element*); // this
bool operator>(const Element*) const; // ,
// ,
124
bool operator>=(const Element*) const; // ,
//
bool operator==(const Element*) const; // ,
//
};
, .
<< >> ,
++,
. << >>
:
<< Next().
>> Set&
operator|=(Element*) .
,
Element*, Set. >> ,
(, ).
3 .
, .
= .
. ,
:
void InsertBefore(Foo* f); // f
void InsertAfter(Foo* f); // f
void RemoveAt(); //
,
. ,
Next(),
.
,
, . ,
,
. , ,
! ,
. ,
.
.
A B
A B
. , .
, :
125
B,
.
B A,
- A , - B .
B, A ,
, - A .
A, B ,
.
,
.
A B ,
, !
,
. ,
.
. , ,
( , ),
.
A B
/ ,
.
A , , , B .
A, B .
.
,
. ,
:
1. .
2.
. , ,
. ,
,
.
, .
, ,
, () .
, , , ,
++,
.
126
, :
. :
class Iterator {
private:
Collection collection;
Cursor location; //
public:
Iterator(Collection& c)
: collection(c), location(collection.First()) {}
bool More();
Foo* Next();
};
Collection
. ,
, ; collection
location,
First().
?
,
, .
.
template <class Type, int Size>
class Array {
private:
int Size; // Type
Type elements[size]; // ()
// ..
};
. ,
, .
, ,
, .
.
,
. , , ,
, . ,
, 4 .
,
.
, , ?
. , ,
.
:
class SimpleCollection; //
class ComplexCollection {
127
public:
operator SimpleCollection*();
};
, SimpleCollection
. ,
- ,
SimpleCollection. .
,
. .
, :
class Iterator {
private:
SimpleCollection* collection;
Cursor location; //
public:
Iterator(SimpleCollection* c)
: collection(c), location(collection->First()) {}
bool More();
bool Next();
};
, . :
(,
SimpleCollection) . (internal iterator)
(external iterator) .
, ,
. ,
,
. . ,
, .
, *-
.
. ,
9. ,
, , .
(. )
,
, .
:
class ExternalIterator {
private:
SimpleCollection collection;
SimpleIterator* my_iter; //
public:
ExternalIterator(ComplexCollection* c)
{
InternalIterator* iter = c->Iterator();
128
while (c->More())
collection += *(c->Next());
delete iter;
my_iter = collection->Iterator();
}
bool More() { return my_iter->More(); }
bool Next() { return my_iter->Next(); }
};
ComplexCollection , ,
. SimpleCollection ,
More() Next() . ,
, SimpleCollection ComplexCollection
ComplexCollection operator SimpleCollection().
.
(persistent) , ,
(my_iter ).
, ,
.
:
// .h
class Collection {
public:
class ExternalIterator {
public:
virtual bool More() = 0;
virtual Foo* Next() = 0;
};
ExternalIterator* Iterator();
};
// .cpp
// ,
class RealExternalIterator
: public ExternalIterator, private InternalIterator
(...);
Collection:ExternalIterator* Collection::Iterator()
{
return new RealExternalIterator(this);
}
ExternalIterator ,
. , RealExternalIterator,
Collection::ExternalIterator , (
) SimpleIterator .
++, ,
. , ,
.
129
, More(). ,
Next() ,
Next(). , ,
, .
More() , ,
Next().
Peek(). ,
Next(), .
:
class RealExternalIterator : public ExternalIterator {
private:
InternalIterator* iter;
bool Accept(Foo*); //
public:
RealExternalIterator(Collection* c) : iter(c->Iterator()) {}
virtual bool More()
{
while (iter.More()) {
if (Accept(iter->Peek()))
return true;
(void)iter->Next(); //
}
return false;
}
virtual Foo* Next() { return iter->Next(); }
};
, More() ( ),
, ,
Accept() .
, Peek(),
,
.
, .
, ,
. , Accept()
.
.
, ,
. -: (
); - ;
.
. - ,
.
, , ,
, .
, .
, 4.
130
.
, ;
, , .
, ,
.
. ,
++. ,
.
. ,
. : = .
Timestamp Timestamp ,
, Timestamp
, .
class Timestamp {
private:
static int last_time; //
int stamp;
public:
Timestamp() : stamp(++last_time) {}
bool operator>(Timestamp ts) { return stamp > ts.stamp; }
bool operator>=(Timestamp ts) { return stamp >= ts.stamp; }
bool operator<(Timestamp ts) { return stamp < ts.stamp; }
bool operator<=(Timestamp ts) { return stamp <= ts.stamp; }
bool operator==(Timestamp ts) { return stamp == ts.stamp; }
bool operator!=(Timestamp ts) { return stamp != ts.stamp; }
};
,
. .
:
class InternalIterator {
public:
bool More(Timestamp as_of);
Foo* Next(Timestamp as_of);
bool Peek(Timestamp as_of);
};
, .
, ,
.
, ,
. ,
, .
131
. (, ),
.
:
class RealExternalIterator : public ExternalIterator {
private:
InternalIterator* iter;
Timestamp my_time; // this
bool Accept(Foo*); //
public:
RealExternalIterator(Collection* c) : iter(c->Iterator()) {}
virtual bool More() {
while (iter.More(my_time)) {
if (Accept(iter->Peek(my_time)))
return true;
(void)iter->Next(my_time);
}
return false;
}
virtual Foo* Next() { return iter->Next(my_time); }
};
Timestamp .
Accept() true, .
,
. ;
.
,
. ,
, .
.
. , ,
.
, .
, ,
void* void* . Slot,
. :
class Dictionary {
public:
Dictionary(); //
Dictionary(const Dictionary&); //
~Dictionary();
Dictionary& operator=(const Dictionary&);
};
AddEntry() .
, . At()
, , ; ,
true value (, ). RemoveEntry()
. First() ,
, GetNext() . GetCurrent()
/, Slot. GetNext()
/ .
.
: , ,
/ .
, /
. Timestamp
/, . ,
.
class History {
public:
History(); //
void Insert(Timestamp); //
void Remove(Timestamp); //
bool Exists(Timestamp); //
bool Exists(); //
};
Exists(Timestamp) true,
, false
. Exists() Exists(Timestamp)
.
: , void*,
, .
:
// Set.h
class SetBase : private Dictionary {
friend class InternalIterator;
protected:
SetBase(); //
133
public:
class Iterator { //
public:
virtual bool More() = 0;
virtual Type* Next() = 0;
};
};
Iterator* SetBase::ProvideIterator()
{
return new InternalIterator(this);
}
void SetBase::AddObject(void* entry)
{
void* v;
History* h;
if (At(entry, v)) { //
h = (History*)v;
if (!h->Exists()) //
h->Insert(Timestamp());
}
else { //
h = new History;
h->Insert(Timestamp());
AddEntry(entry, h);
}
}
void SetBase::RemoveObject(void* entry)
{
void* v;
History* h;
if (At(entry, v)) { //
h = (History*)v;
if (h->Exists()) //
h->Remove(Timestamp());
}
}
bool SetBase::Exists(void* entry, Timestamp ts)
{
void* v;
return At(entry, v) && ((History*)v)->Exists(ts);
}
bool SetBase::Exists(void* entry)
{
void* v;
return At(entry, v) && ((History*)v)->Exists();
}
, ,
.
134
ProvideIterator(),
, .cpp SetBase::Iterator,
, .
, ( .cpp).
.
// set.cpp
class InternalIterator : public SetBase::Iterator {
private:
Dictionary* dictionary;
Dictionary::Slot* slot; //
Timestamp my_time; //
public:
InternalIterator(Dictionary* d)
: dictionary(d), slot(d->First()), my_time() {}
virtual bool More();
virtual void* Next();
};
bool InternalIterator::More()
{
void* key;
void* h;
if (!dictionary->GetCurrent(slot, key, h))
return false; //
do
if (((History*)h)->Exists(my_time))
return true;
while (dictionary->GetNext(slot, key, h));
return false;
}
void* InternalIterator::Next()
{
void* key;
void* key1;
void* h;
// , More(),
// GetNext()
dictionary->GetCurrent(slot, key, h);
dictionary->GetNext(slot, key1, h);
return key;
}
,
,
.
, SetBase.
template <class Type>
class Set : private SetBase {
135
public:
//
//
// =
Set<Type>& operator+=(Type* object)
{ AddObject(object); return *this; }
Set<Type>& operator-=(Type* object)
{ RemoveObject(object); return *this; }
bool operator>=(Type* object)
{ return Exists(object); }
class Iterator {
private:
SetBase::Iterator* iter;
public:
Iterator(Set&* i) : iter(s.ProvideIterator()) {}
bool More() { return iter->More(); }
Type* Next() { return (Type*)(iter->Next()); }
};
Iterator* ProvideIterator()
{ return new Set::Iterator(*this); }
};
, ,
, .
,
. , :
Set::Iterator iter(aSet);
,
. : SetBase
. SetBase .cpp,
. Set =,
.
9
, (, ,
). , .
,
. ,
, .
, , , .
. , ,
, .
: , .
,
. , .
,
. ,
, .
/ ,
.
, (transaction),
.
, :
1. . ,
, .
2. ,
.
; ,
.
3. ,
.
, .
:
138
1. ,
. ,
.
2. ,
. ,
, .
(deadlock): A X
Y, B Y
X.
,
. ++,
.
. ,
. - ,
, .
, ,
,
.
( Lisp)
. . .
++ ; 3
.
++, : , .
.
, Undo
. ,
, . ,
. .
, ,
Undo
, . ,
.
?
, , ,
.
. ,
, ( - ) ++
. : ++ ,
.
, .
?
: (image)
, .
,
,
. ,
++ (image pointer).
139
. ,
.
.
, , , .
template <class Type>
class ImagePtr {
private:
Type* current; // ,
Type* undo; //
public:
ImagePtr() : undo(NULL), current(new Type) {}
ImagePtr(const ImagePtr<Type>& ip)
: current(new Type(*(ip.current))), undo(NULL) {}
~ImagePtr() { delete current; delete undo; }
ImagePtr<Type>& operator=(const ImagePtr<Type>& ip)
{
if (this != &ip) {
delete current;
current = new Type(*(ip.current));
}
return *this;
}
void Snapshot()
{
delete undo; // ,
undo = current;
current = new Type(*undo);
}
void Commit()
{
delete undo;
undo = NULL;
}
void Rollback()
{
if (undo != NULL) {
delete current;
current = undo;
undo = NULL;
}
}
Type* operator->() const { return current; }
};
->,
. Shapshot()
. ,
Rollback(); , Commit().
140
= ,
. :
, .
, ,
.
, Commit(), -
, . ;
- , .
Rollback() Commit(), ,
.
.
. ,
Stack Empty(), Push(), Pop() DeleteAll().
Pop() NULL, . DeleteAll()
.
. , , . ,
. Rollback() .
= ,
.
template <class Type>
class ImageStackPtr {
private:
Type* current; // ,
Stack<Type> history; //
public:
ImageStackPtr() : current(new Type) {}
ImageStackPtr(const ImageStackPtr<Type>& ip)
: current(new Type(*(ip.current))) {}
~ImageStackPtr() { delete current; }
ImageStackPtr<Type>& operator=(const ImageStackPtr<Type>& ip)
{
if (this != &ip) {
history.DeleteAll();
delete current;
current = new Type(*(ip.current));
}
return *this;
}
void PushImage()
{
history.Push(current);
current = new Type(*current);
}
void Commit() { history.DeleteAll(); }
void PopImage() //
{
if (!history.Empty()) {
delete current;
current = history.Pop();
141
}
}
void Rollback() //
{
Type* old = history.Pop();
Type* oldere = NULL;
if (old != NULL) { //
while ((older = history.Pop()) != NULL) {
delete old;
old = older;
}
delete current;
current = old;
}
}
Type* operator->() const { return current; }
};
,
.
, .
, .
, ,
new *-, .
,
,
.
template <class Type>
class AutoImage {
private:
Type current;
Type image;
bool have_image; // ,
public:
AutoImage() : have_image(false) {}
AutoImage(const AutoImage<Type>& ai)
: current(ai.current), image(), have_image(false) {}
AutoImage<Type>& operator=(const AutoImage<Type>& ip)
{
if (this != &ip) {
current = ip.current;
have_image = false;
}
return *this;
}
AutoImage<Type>& operator=(const Type& t)
{
current = t;
142
return *this;
}
operator Type&() { return current; }
void Snapshot()
{
image = current;
have_image = true;
}
void Commit() { have_image = false; }
void Rollback()
{
current = image;
have_image = false;
}
bool HaveImage() { return have_image; }
};
, :
1. , , .
AutoImage current image.
2. , , =
, , .
Shapshot() Rollback().
( int double) .
, =. C++,
, ,
BASIC.
, , .
AutoImage ImagePtr ImageStackPtr
image have_image
false. = ,
image.
, have_image false.
image ,
, false
have_image, :
1. image Type Type* new.
,
.
2. 13.
, , image -
, unsigned char image(sizeof Type)
Type . ++ , ,
, 13.
AutoImage , ->:
Type* operator->() { return ¤t; }
: ->
, current *this , ->
current.
143
. Foo
, ,
.
class Foo {
private:
AutoImage<int> some_integer;
AutoImage<Bar> bar;
public:
void Rollback()
{
some_integer.Rollback();
bar.Rollback();
}
void Commit()
{
some_integer.Commit();
bar.Commit();
}
void Snapshot()
{
some_integer.Snapshot();
bar.Snapshot();
}
int ProvideInt() const { return some_integer; }
void ChanheInt(int new_value)
{
if (!some_integer.HaveImage())
some_integer.Snapshot();
int&(some_integer) = new_value;
}
const Bar& ProvideBar() const { return bar; }
Bar& UpdateBar()
{
if (!bar.HaveImage())
bar.Shapshot();
return Bar&(bar);
}
};
, Bar . ,
, . int
. ,
, . ,
bar, , . ,
ProvideBar(), const Bar&,
Bar&, . :
.
++,
->:
const Type* operator->() const; //
Type* operator->() const; //
144
, ,
++ .
++, .
Foo.
. , Foo::Commit()
Commit() . ;
, : Commit()
. , (
), .
AutoImage
*-.
, .
, , .
, .
AutoImage<Foo*> f;
f , NULL.
, *-
->,
(- ptr->MemberOfPointer();). *- AutoImage
, 5.
( !) .
template <class Type>
class PtrImage {
private:
Type* current;
Type* image;
bool have_image; // ,
public:
PtrImage() : current(NULL), image(NULL), have_image(false) {}
PtrImage(const PtrImage<Type>& pi)
: current(pi.current), image(NULL), have_image(false) {}
PtrImage<Type>& operator=(const PtrImage<Type>& pi)
{
if (this != &pi)
current = pi.current;
return *this;
}
PtrImage<Type>& operator=(Type* t)
{ current = t; return *this; }
operator Type*() { return current; }
Type* operator->() const { return current; }
bool operator!() { return current == NULL; }
void Snapshot()
{
image = current;
have_image = true;
}
void Commit() { image = NULL; have_image = false; }
145
void Rollback()
{
if (have_image) {
current = image;
have_image = false;
}
bool HaveImage() { return have_image; }
};
, Snapshot()
operator=().
, .
, (
),
, .
,
. ,
:
/ ;
/ new;
/ ;
/ ;
/ Snapshot().
.
, .
++ ( ,
). ,
. .
, . ,
. ,
.
, :
template <class Type>
class ImagePtr {
private:
Type* current; // ,
Type* undo; //
public:
ImagePtr();
ImagePtr(const ImagesPtr<Type>& ip);
~ImagePtr();
ImagePtr<Type>& operator=(const ImagePtr<Type>& ip);
void Snapshot();
void Commit();
146
void Rollback();
Type* operator->() const;
};
:
.
.
, ,
.
, ,
++ .
Transaction. .
, , ,
- .
( ) .
:
1. ,
.
2. ,
.
, ,
. ,
, . ,
, ,
.
// Transaction.h
class Lock {
friend class Transaction;
protected:
Transaction* transaction; // , this
Lock() : transaction(NULL) {}
void RegisterLock(Transaction* t)
{
if (transaction != NULL) {
//
cerr << Lock::RegisterLock already locked << endl;
}
else {
t->AddLock(this);
transaction = t;
}
}
virtual ~Lock() {}
virtual void Rollback() = 0;
virtual void Commit() = 0;
};
class Transaction {
friend class Lock; // AddLock()
147
private:
SafeSet<Lock>* locks;
void AddLock(Lock*); //
public:
~Transaction();
void Commit(); //
void Rollback(); //
bool OwnsLock(Lock*); // ,
//
};
Transaction
Collection. RegisterLock() Lock
AddLock() Transaction. ,
Lock .
.
void Transaction::AddLock(Lock* lock)
{
*locks += lock; // +=
}
void Transaction::Commit()
{
SafeSetIterator<Lock>* iter = locks->Iterator();
while (iter->More())
iter->Next()->Commit();
delete iter;
}
void Transaction::Rollback()
{
SafeSetIterator<Lock>* iter = locks->Iterator();
while (iter->More())
iter->Next()->Rollback();
delete iter;
}
bool Transaction::OwnsLock(Lock* lock)
{
return *locks >= lock;
}
, Collection DeleteAll()
; += ( operator+=(Type*))
; >= ,
Iterator() . ; ,
.
ConstPtr
, Lock, ,
, .
template <class Type>
class LockPtr; // , Lock
148
template <class Type>
class ConstPtr {
friend class LockPtr<Type>;
private:
Type* old_image; //
LockPtr<Type>* lock; // ,
~ConstPtr() { delete old_image; }
ConstPtr<Type>& operator=(const ConstPtr<Type>& cp)
{ return *this; } //
public:
ConstPtr() : old_image(NULL), lock(NULL) {}
ConstPtr(const ConstPtr<Type>& cp)
: old_image(new Type(*(cp.old_image))), lock(NULL) {}
const Type* operator->() const { return old_image; }
LockPtr<Type>& Lock(Transaction* t);
};
template <class Type>
LockPtr<Type>& ConstPtr<Type>::Lock(Transaction* t)
{
if (lock != NULL && !t->OwnsLock(lock))
//
else {
lock = new LockPtr<Type>(t, this);
return *lock;
}
}
ConstPtr (
), ,
LockPtr, ConstPtr. =
, . ,
( ,
). ,
ConstPtr.
Lock :
.
, ,
.
LockPtr<Type>* NULL,
.
!,
.
CanLock(Transaction*),
.
. ;
.
149
LockPtr
! ,
. ( )
ConstPtr, LockPtr. LockPtr
Rollback() Commit(). Snapshot() ,
LockPtr ->.
template <class Type>
class LockPtr : public Lock {
friend class ConstPtr<Type>;
private:
ConstPtr<Type>* master_ptr;
Type* new_image;
Transaction* transaction;
LockPtr(Transaction* t, ConstPtr<Type>* cp);
virtual ~LockPtr();
virtual void Rollback();
virtual void Commit();
public:
Type* operator->() const { return new_image; }
};
template <class Type>
LockPtr<Type>::LockPtr(Transaction* t, ConstPtr<Type>* cp)
: transaction(t), master_ptr(cp), new_image(new Type(*(cp->old_image)))
{
}
template <class Type>
LockPtr<Type>::~LockPtr()
{
//
delete new_image; //
master_ptr->lock = NULL; // ConstPtr
}
template <class Type>
void LockPtr<Type>::Rollback()
{
delete new_image;
new_image = new Type(*(master_ptr->old_image));
}
template <class Type>
void LockPtr<Type>::Commit()
{
delete master_ptr->old_image;
master_ptr->old_image = new_image; // master_ptr
new_image = new Type(*new_image); //
}
, LockPtr.
- Lock. Rollback() Commit()
, ,
150
(, ).
ConstPtr .
- . ,
, .
. ,
, .
ConstPtr, LockPtr. ,
ConstPtr , ConstPtr
. .
ConstPtr
,
LockPtr. LockPtr,
ConstPtr Lock(). , ConstPtr
Lock(). ConstPtr
NULL , LockPtr
. ConstPtr :
old_image NULL.
!, , NULL.
->, NULL.
, old_image NULL.
ConstPtr ,
, .
ConstPtr. ,
.
private:
ConstPtr(const ConstPtr&) : old_image(NULL), lock(NULL) {}
public:
ConstPtr() : old_image(NULL), lock(NULL) {}
bool operator!() { return old_image == NULL; }
const Type* operator->() const
{
if (old_image == NULL)
//
return old_image;
}
LockPtr
LockPtr :
.
Make().
-> , NULL.
.
// LockPtr
public:
void Make(); //
void Destroy(); //
151
//
template <class Type>
LockPtr<Type>::LockPtr(Transaction* t, ConstPtr<Type>* cp)
: transaction(t), master_ptr(cp),
new_image(cp->old_image != NULL ? new Type(*(cp->old_image)) : NULL)
{
}
template <class Type>
void LockPtr<Type>::Commit()
{
delete master_ptr->old_image;
master_ptr->old_image = new_image;
if (new_image != NULL)
new_image = new Type(*new_image);
}
template <class Type>
Type* LockPtr<Type>::operator->() const
{
if (new_image == NULL)
//
return new_image;
}
template <class Type>
void LockPtr<Type>::Make()
{
delete new_image; // new_image NULL
new_image = new Type; //
}
template <class Type>
void LockPtr<Type>::Destroy()
{
delete new_image;
new_image = NULL;
}
Make() ,
. , LockPtr,
.
:
1. ConstPtr, NULL.
2. Lock.
3. Lock Make().
,
, new.
, , .
, ConstPtr
.
152
ConstPtr<Type>::ConstPtr(Transaction* t) : old_image(NULL), lock(NULL)
{
LockPtr<Type>& lp = Lock(t);
lp.Make();
}
Lock() LockPtr.
. , ,
.
. -
. , Delete Edit
Delete . , .
,
Undo Edit. ,
, .
, .
, , , ,
. ,
.
- ,
ContrPtr LockPtr. ,
, ,
. ,
ConstPtr LockPtr, .
class A {
private:
ConstPtr<B>& b; // ConstPtr,
// ..
};
A b,
LockPtr b. , A ,
b, . ,
, , ,
, (
, ).
(
), .
, =
.
ConstPtr LockPtr .
, (
A B , ):
class A {
private:
153
B b; //
};
B A,
= B .
, A b. Transaction*? , A
. , :
Transaction* A,
B.
Transaction* A .
ConstPtr A
A.
: .
. ,
.
, A B*
ConstPtr LockPtr. ConstPtr / LockPtr A
.
, / .
.
, .
,
. , -
, ,
. ,
,
.
(conservative locking) ,
, - . ,
, , ,
.
, Transaction
( )
( ).
(aggressive locking)
. ,
.
, ,
. ,
, .
, ,
.
, ,
.
154
,
.
( A
B, B A). ,
. , ,
- , , ,
.
,
,
. ,
, ++,
. , ,
.
(
StackPtr, ). .
LockPtr
LockPtr.
StackPtr. , .
.
, LockPtr .
LockPtr/
Transaction ,
/LockPtr. LockPtr,
. ,
.
,
ConstPtr ( ). ConstPtr
, 6
: ConstPtr Lock().
.
(,
Transaction), , Transaction
ConstPtr. LockPtr. ,
Lock() ConstPtr, , this .
, , ,
. ConstPtr , (ConstPtr,
Transaction, LockPtr), .
, ;
NULL . ,
,
.
, Lock() ConstPtr?
?
LockPtr* Lock(), ConstPtr
, . ,
? LockPtr - ; ,
155
. , Transaction
LockPtr .
, Lock . .
ConstPtr .
,
. ,
,
ConstPtr/LockPtr. ,
++, :
1. , , .
2. , .
,
.
++,
, , ,
, . ++,
, ( , =
->).
. , ,
-> ConstPtr LockPtr. ++
, .
, ,
, ,
. : . ,
,
.
3
,
, .
++, . ,
, . ,
++,
, .
, , .
. , ,
,
.
10
, -
. ,
++, .
,
. , .
: , ,
, ?
switch/case, ,
, ,
(multiple dispatch).
.
, ! 12
,
.
,
. -
(Grandpa). , Grandpa
, .
class Grandpa {
public: //
virtual void Fn1() = 0;
virtual void Fn2(int) = 0;
};
, Grandpa . ,
Grandpa .
, -. ,
- ,
.
. , Grandpa
. Grandpa ,
. ,
.
class Dad : public Grandpa {
private:
//
160
protected:
// ,
public:
virtual void Fn1();
virtual void Fn2(int);
};
class AuntMartha : public Grandpa {
private:
//
protected:
// ,
public:
virtual void Fn1();
virtual void Fn2(int);
};
, - , .
: ,
, .
;
, . .
- ,
.
, .
,
. - , ?
, ,
, .
,
, , . Dad
, Grandpa
: ?
,
.
.
, ,
Grandpa ,
.
Grandpa
. ,
. . ,
Fn1() Grandpa :
void Grandpa::Fn1()
161
{
// ,
}
void Dad::Fn1()
{
// ,
}
void AuntMartha::Fn1()
{
Grandpa::Fn1();
//
}
Grandpa . , ,
, .
, , , ,
.
. Grandpa ,
Grandpa , .
Dad Grandpa Fn1()
Grandpa::Fn1(). Grandpa::Fn1() .
Grandpa, , , Dad . AuntMartha
Grandpa::Fn1()
Grandpa::Fn1(). AuntMartha
Grandpa .
, ,
. , ,
. , - .
, ,
.
,
.
Grandpa
. ;
, ( )
.
.
Grandpa, ,
. , Grandpa
? : .
, ,
, . (
) .cpp.
// .h
class Grandpa { ... };
// (-) .cpp
class Dad : public Grandpa { ... };
class AuntMartha : public Grandpa { ... };
; , , .
162
,
, .
. ,
, Dad, .h?
, .
.h, ,
.
,
: , , .. -
Number :
class Number {
public:
virtual Number operator+(const Number&) = 0;
virtual Number operator-(const Number&) = 0;
// ..
};
class Integer : public Number {
private:
int i;
public:
Integer(int x) : i(x) {}
virtual Number operator+(const Number&);
// ..
};
, .
Integer::operator+(Number&), , Number,
? , ,
. Complex + Integer Integer + Real, ,
, Integer + ArbitraryPrecisionNumber. ,
? -? : +
? .
class Number {
protected:
int type; //
int TypeOf() { return type; }
// ..
};
// -
switch (type) {
case kInteger: ...
case kComplex: ...
}
. ,
. - ,
switch/case? , .
v-.
163
,
, .
.
,
.
, ,
. ( )
(double dispatch).
class Number {
protected:
// +
virtual Number& operator+(const Integer&) = 0;
virtual Number& operator+(const Complet&) = 0;
// ..
public:
virtual Number& operator+(const Number&) = 0;
virtual Number& operator-(const Number&) = 0;
// ..
};
class Integer : public Number {
private:
int I;
protected:
virtual Number& operator+(const Integer&);
virtual Number& operator+(const Complex&);
public
Integer(int x) : i(x) {}
virtual Number& operator+(const Number&);
// ..
};
Number& Integer::operator+(const Number& n)
{
return n + *this; //
}
Number& Integer::operator+(const Integer& n)
{
//
if (i + n.i int) {
return
}
else return Integer(i + n.i);
}
, ,
.
, .
Integer, Integer::operator+(),
operator+(Number&)
. Integer::operator+(Number&)
164
, .
: return n + *this. ,
v- n.
Number::operator+(Integer&), , *this Integer.
Integer::operator+(Integer&),
. , ,
, . ,
: Number
v-.
. , , ,
. , ,
switch/case? ,
v-.
,
:
m n ,
m*(n+1) ,
-. (m+1)*m*(n+1) .
, , .
(
, ), ,
. ,
y/x , x/y; /
DivideInto .
,
.
,
, , .
. , ,
switch/case .
, ,
,
. .
Number ;
12. ++, ,
,
.
, ,
. ,
.
.
: , ,
, . ,
, (
)
, , .
. , ,
. , .
class Event { //
public:
165
virtual void Process(View* v) = 0;
};
class MouseClick : public Event {
public:
virtual void Process(View* v) { v->Process(*this); }
};
class View { //
public:
virtual void Process(MouseClick& ev) = 0;
virtual void Process(Keystroke& ev) = 0;
// ..
};
, Number,
. Process() Event
. Event::Process() ,
View, Event ,
View::Process().
, , ,
, ,
( ).
,
. n
, n . , ,
Number Number&. ,
-> ( .), .
class Number {
protected:
// this
virtual Number& fn1(Integer& n1, Number& n3) = 0;
virtual Number& fn1(Complex& n1, Number& n3) = 0;
// ..
// this
virtual Number& fn2(Integer& n1, Integer& n2) = 0;
virtual Number& fn2(Integer& n1, Complex& n2) = 0;
virtual Number& fn2(Complex& n1, Integer& n2) = 0;
virtual Number& fn2(Complex& n1, Complex& n2) = 0;
// ..
public:
// this
virtual Number& fn(Number& n2, Number& n3) = 0;
};
class Integer : public Number {
protected:
// this
virtual Number& fn1(Integer& n1, Number& n3)
{ return n3.fn2(n1, *this); }
virtual Number& fn1(Complex& n1, Number& n3)
166
{ reutrn n3.fn2(n1, *this); }
// ..
// this
virtual Number& fn2(Integer& n1, Integer& n2)
{
//
}
// ..
public:
// this
virtual Number& fn(Number& n2, Number& n3)
{ return n2.fn1(*this, n3); }
};
, , .
v-, ,
. .
, ;
, .
,
-: .
,
.
, , .
, ,
. ,
, .
. , -
.
.
(clustering). ,
.
++.
(, ), if/then/else
switch/case, .
:
1.
.
2.
, .
, .
,
.
.
.
167
,
, !.
class foo { ... };
class bar : public foo { ... };
class banana : public bar { ... };
void fn(bar&);
void fn(foo&);
fn(*(new banana)); // ! --!
,
, . fn()
banana&,
.
.
.
. ,
, (Complex),
Complex.
. ,
(Real); , Real.
Complex, Real, Rational .. Integer (
) Rational, Real Complex ,
Integer Complex. , :
( ) ,
?
, . -,
,
. , ,
,
. -, +=?
Integer+=Complex, Complex,
.
11 12 ,
(,
Event/View). ,
, , .
v- .
, , Number&?
Number& Integer::operator+(const Integer& n)
{
//
if (i + n.i int) {
return
}
else return Integer(i + n.i);
}
.
, .
168
new ( ) ,
.
? , 11
12, (, ),
.
, (,
),
.
11
. ,
.
. .cpp ,
? .
(factory function) ,
new . ++ ,
, .
?
, .
,
++ (, ).
RTTI (Run Time Type Information, ),
, ,
. ,
, .
, , ,
.
// Grandpa.h
class Grandpa { ... };
// Grandpa.cpp
class Dad : public Grandpa { ... };
class AuntieEm : public Grandpa { ... };
// -
#include Grandpa.h
Grandpa* g = new ... // ! ?
, , ++, ?
, (Dad)
, Grandpa.cpp.
170
Grandpa ,
Dad, !
make-
.
makeFoo(), Foo .
class Grandpa {
public:
static Grandpa* makeDad(); // Dad
static Grandpa* makeAuntieEm();
};
// Grandpa.cpp
Grandpa* Grandpa::makeDad()
{
return new Dad;
}
Grandpa* Grandpa::makeAuntieEm()
{
return new AuntieEm;
}
- ,
Dad AuntieEm .
make-
makeFoo ++, ?
make.
class Variation Dad {}; //
class VariationAuntieEm {};
class Grandpa {
public:
static Grandpa* make(VariationDad);
static Grandpa* make(VariationAuntieEm);
};
//
Grandpa* g = Grandpa::make(VariationDad());
. , Grandpa
, .
171
. , ,
, . ,
.
class Number {
public:
static Number* make(); //
static Number* make(int);
static Number* make(double);
static Number* make(string); // , -1.23
};
// .cpp
class Integer : public Number { ... };
class Real : public Number { ... };
class ArbitraryPrecisionNumber : public Number { ... };
Number* Number::make()
{
return new Integer(0);
}
Number* Number::make(int x)
{
return new Integer(x);
}
Number* Number::make(double x)
{
return new Real(x);
}
Number* Number::make(string s)
{
//
if ( )
return new Integer(atoi(s));
if ( )
return new ArbitraryPrecisionNumber(s);
if ()
// ..
}
. ,
, ,
. ,
.
, . ,
, , .cpp
, .
class Window {
public:
172
static Window* make();
//
};
// window.cpp Windows
class MS_Window : public Window { ... };
Window* Window::make()
{
return MS_Window();
}
// window.cpp Mac OS
class Mac_Window : public Window { ... };
Window* Window::make()
{
return Mac_Window*();
}
,
.cpp. Window
(, ,
,
).
(junkyard functions) .
, , ,
delete.
class Grandpa {
protected:
virtual ~Grandpa();
public:
static Grandpa make();
static void destroy(Grandpa*);
};
// grandpa.cpp
void Grandpa::destroy(Grandpa* g)
{
delete g;
}
, ,
.
, .
, - .
:
, .
// grandpa.h
class Grandpa {
public:
//
173
};
// grandpa.cpp
class RealGrandpa : public Grandpa {
//
protected:
//
};
class Dad : public RealGrandpa { ... };
class AuntieEm : public RealGrandpa { ... };
, .
RealGrandpa,
.cpp. .h!
=!
, Grandpa ,
. Grandpa
.
, ,
.
, ,
=.
- , make-
this.
class Grandpa {
public:
virtual Grandpa* makeClone() = 0;
};
,
. . =
, , , .
= . : =
AssignTo(),
. , .
,
. ,
. (,
), .
class GrandpaClass { // Grandpa
public:
Grandpa* make(); // Grandpa
};
class Grandpa { ... };
,
, . ,
, ? -,
, - ,
174
. -,
.
.
.
class Class {
protected:
Collection<Class> base_classes;
Collection<Class> derived_classes;
String class_name;
Class() {}; //
public:
// ..
};
,
SmallTalk .
, ,
. , ,
. ,
, ++
(instantiate by name).
// -
Class* c = gClasses.Find(Grandpa);
???* g = (Grandpa*)c->make(???);
, .
, Grandpa,
, .
.
, . ,
. n
, .
, Class make(istream&)
. :
//
cin << className;
Class* c = gClasses.Find(className);
BasClass* obj = c->make(cin);
,
Class. :
Class , . ,
Class, .
Class ,
SmallTalk Lisp .
(, ),
. (, ,
), .
175
Class ,
. .
Class ,
/Class, Class.
:
1. , ( int).
, Class.
2. , Class.
3. .
.
Class
. ++,
. .
, ( ) (, ,
).
++; ,
.
Class
. Class,
(Class, ).
, (
x),
? Class .
, ;
( ) .
,
; , ;
, ,
. ,
.
, , .
, ,
. ,
( ), ,
.
, ,
.., , ,
, . .
Class. - ,
. . !
.
, ,
176
,
, .
.
, . ,
, ,
. .
Class , .
class Object { //
protected:
static ObjectClass s_my_class;
Class* my_class; // == &s_my_class;
public:
Object() : my_class(&s_my_class) {}
Class* My_Class() { return my_class; }
};
class Foo : public Object
protected:
static FooClass s_my_class;
public:
Foo() { my_class = &s_my_class; }
};
Object,
Class.
( s_my_class ). ,
. ,
/ / ,
my_class . Class
, .
, .
, v- , .
my_class ,
. ,
, .
Class Class:
class Object {
friend class Class;
private:
Class* my_class;
public:
Class* My_Class() { reutrn my_class; }
};
class Class {
protected:
void SetClass(Object& obj) { obj.my_class = this; }
};
class Foo : public Object { ... };
177
class FooClass : public Class {
public:
Foo* make()
{
Foo* f = new Foo;
this->SetClass(f);
return f;
}
};
, Object
? , Foo,
. ,
:
, .
, .
, 4.
, /Class.
, , Class
. ,
,
,
.
, 15 16
.
,
.
. , ( foo)
Foo.
, this ,
.
178
, .
:
Class.
(
, ).
.
.
, /,
, , .
,
.
12
++ .
. , - ,
. ,
, . :
, . ,
.
,
. (invisible pointers),
,
. (James Coplien)
/;
.
, , .
:
.
class Foo {
public:
virtual void do_something() = 0;
virtual void do_something_else() = 0;
};
class PFoo : public Foo {
private:
Foo* foo;
public:
virtual void do_something() { foo->do_something(); }
virtual void do_something_else() { foo->do_something_else(); }
};
class Bar : public Foo {
//
};
-> PFoo .
. ,
, .
180
,
.cpp.
. , Foo,
PFoo , .
, ,
,
. .
// foo.h
class Foo {
public:
static Foo* make(); //
virtual void do_something() = 0;
virtual void do_something_else() = 0;
};
// foo.cpp
class PFoo : public Foo {
private:
Foo* foo;
public:
PFoo(Foo* f) : foo(f) {}
virtual void do_something() { foo->do_something(); }
virtual void do_something_else() { foo->do_something_else(); }
};
class Bar : public Foo {
//
};
Foo* Foo::make()
{
return new PFoo(new Foo);
}
PFoo ,
,
Bar. , ?
- ,
, .
, .
, ,
. ,
.
: .
. , PFoo
Foo. , ( ) ,
.
, ,
, .
.
181
, ,
. , .
, .
Foo*. Foo&.
class Foo {
public:
static Foo& make(); //
virtual void do_something() = 0;
virtual void do_something_else() = 0;
};
// foo.cpp
class PFoo : public Foo {
private:
Foo* foo;
public:
PFoo(Foo* f) : foo(f) {}
virtual void do_something() { foo->do_something(); }
virtual void do_something_else() { foo->do_something_else(); }
};
class Bar : public Foo {
//
};
Foo& Foo::make()
{
return *(new PFoo(new Foo));
, ,
, . , &,
. * .
.
, . ,
, .
.
,
. , (
make-).
.
class Foo {
private:
Foo(const Foo&) {}
public:
virtual Foo* makeClone(); //
};
// foo.cpp
182
class PFoo : public Foo {
private:
Foo* foo;
public:
PFoo(Foo* f) : foo(f) {}
virtual Foo* makeClone() { return new PFoo(foo); }
};
Foo* Foo::makeClone()
{
return NULL; // ,
}
makeClone() . ,
, - .
, , = ,
. ,
, . ,
= .
class Foo {
public:
virtual Foo& operator=(const Foo&);
};
// foo.cpp
class PFoo : public Foo {
private:
Foo* foo;
public:
virtual Foo& operator=(const Foo& f)
{
foo = f.foo;
return *this;
}
};
Foo& Foo::operator=(const Foo&)
{
return *this;
}
:
,
: , ? ,
, ,
:
1. , ,
. 1 0,
.
183
2. ,
. ,
, .
, - .
, 16.
(
).
, ,
:
1. , .
2. , .
3. , ,
.
,
.
- ,
.
class Foo {
public:
virtual ~Foo() {}
};
// foo.cpp
class PFoo : public Foo {
private:
Foo* foo;
public:
virtual ~PFoo() { delete foo; }
};
,
.
makeClone().
class Foo {
protected:
Foo(const Foo&) {}
public:
virtual Foo* makeClone() = 0; //
};
// foo.cpp
class PFoo : public Foo {
private:
Foo* foo;
public:
PFoo(Foo* f) : foo(f) {}
184
virtual Foo* makeClone() { return new PFoo(foo->makeClone()); }
};
class Bar : public Foo {
protected:
Bar(Bar&); //
public:
virtual Foo* makeClone();
};
Foo* Bar::makeClone()
{
return new Bar(*this);
}
.
, . ,
. :
, Foo .
. ,
.
class Foo {
public:
virtual Foo& operator=(const Foo&);
};
// foo.cpp
class PFoo : public Foo {
private:
Foo* foo;
public:
virtual Foo& operator=(const Foo& f)
{
if (this == &f) return *this;
delete foo;
foo = f.foo->makeClone();
return *this;
}
};
Foo& Foo::operator=(const Foo&)
{
return *this;
}
.
, ,
+=. ,
-, 7.
185
, .
,
.
.
, ,
. ,
(. 11), new.
.
// number.h
class NBase; //
class Number {
protected:
Number(const Number&) {}
Number() {}
public:
virtual NBase& operator+(const NBase&) = 0;
virtual Number& operator+(const Number&) = 0;
// ..
};
// number.cpp
class Integer;
class Real;
class PNumber : public Number {
private:
NBase* number;
protected:
virtual NBase& operator+(const NBase& n) const
{ return *number + n; } // #2
public:
PNumber(NBase* n) : number(n) {}
virtual Number& operator+(const Number& n) const
{ return *(new PNumber(&(n + *number))); } // #1
};
,
, . ,
, Number ( PNumber,
). , Integer:
1. PNumber::operator+(const Number&) .
, ,
. , ,
PNumber .
2. PNumber::operator+(const NBase&) .
+ .
3. Integer::operator+(const NBase&)
. .
4. Integer::opeator+(const Integer&)
, .
.
. ,
NBase .
, PNumber,
, :
PNumber::operator+(const Number&)
. PNumber , PNumber,
Number PNumber,
. PNumber::operator+(const NBase&).
.h
NBase.
, -
Number , .
, Number PNumber.
Number .cpp
(Number PNumber) ,
.
?
Number,
delete &aResult.
,
. ANSI ( ),
,
187
.
,
{ return *(new Integer(&(value + i.value)); }
{ return Integer(value + i.value); }
PNumber.
. ,
, makeClone(). PNumber
Number = ,
. ,
, 4.
, ,
. - ,
.
+=, ,
. Complex Integer,
.
// number.h
class NBase; //
class Number {
protected:
Number(const Number&) {}
Number() {}
public:
virtual NBase& AddTo(const NBase&) = 0;
virtual Number& operator+(const Number&) = 0;
// ..
};
// number.cpp
class Integer;
class Real;
class PNumber : public Number {
private:
NBase* number;
protected:
virtual NBase& AddTo(const NBase& n) const
{ return number->AddTo(n); } // #2
public:
PNumber(NBase* n) : number(n) {}
virtual Number& operator+(const Number& n) const
{
number = &(n.AddTo(*number)); // #1 -
return *this;
}
};
, .
.
,
.
,
.
, ,
. ,
, .
, , ?
, ,
, - .
,
(proxy) .
.
. , (master
token): , ,
. ,
.
,
, . ,
, .
4
++, ,
,
.
,
.
, ++,
.
.
!
13
. ,
++ ( ) 50
. ? ,
?
, ?
, SmallTalk Lisp, ++ .
, ++ ; , ,
,
? SmallTalk.
; ,
.
. , ++
, .
, ,
.
new delete.
, ++.
, .
new delete
, new delete ,
. , , .
. delete
. new
new , .
class Foo {
private:
struct FreeNode {
FreeNode* next;
};
static FreeNode* fdFreeList;
194
public:
void* operator new(size_t bytes)
{
if (fgFreeList == NULL)
return ::operator new(bytes);
FreeNode* node = fgFreeList;
FgFreeList = fgFreeList->next;
return node;
}
void operator delete(void* space)
{
((FreeNode*)space->next = fgFreeList;
fgFreeList = (FreeNode*)space;
}
};
, ,
new delete . new ,
, . delete
. ;
. new ,
, v- . delete ,
. ,
delete , ,
delete. Foo,
/ .
, ( )
.
class Bar : public Baseclass, public Foo { ... };
Bar Baseclass,
Foo.
, . -
, , Foo ,
Foo::FreeNode*. , ,
. ( ),
,
FreeNode. , Foo
v- , .
, ,
. .
class Bar : public Foo {
private:
int x;
};
Bar , Foo.
Foo, Bar !
.
new ,
. .
195
class Foo {
public:
void* operator new(size_t bytes)
{
if (bytes != sizeof(Foo) || fgFreeList == NULL)
return ::operator new(bytes);
FreeNode* node = fgFreeList;
FgFreeList = fgFreeList->next;
Return node;
}
};
, .
. delete
. ,
:
class Foo {
public:
void* operator new(size_t bytes); // .
void operator delete(void* space, size_t bytes)
{
if (bytes != sizeof(Foo))
::operator delete(space);
((FreeNode*)space)->next = fgFreeList;
fgFreeList = (FreeNode*)space;
}
};
Foo ,
. , . ?
Foo* foo = new Bar;
delete foo; // ?
Bar Foo, Foo::operator new new.
, . ,
Foo::operator delete, ,
. , Foo, Bar;
. ,
, delete
foo;. , , .
delete , .
, .
, delete 2438-
,
.
, ,
v-.
class Foo {
private:
struct FreeNode {
FreeNode* next;
};
196
static FreeNode* fdFreeList;
public:
virtual ~Foo() {}
void* operator new(size_t bytes)
{
if (bytes != sizeof(Foo) || fgFreeList == NULL)
return ::operator new(bytes);
FreeNode* node = fgFreeList;
FgFreeList = fgFreeList->next;
return node;
}
void operator delete(void* space, size_t bytes)
{
if (bytes != sizeof(Foo))
return ::operator delete(space);
((FreeNode*)space)->next = fgFreeList;
fgFreeList = (FreeNode*)space;
}
};
v- , Foo
(FreeNode*),
, delete.
:
( , ).
new delete.
new delete
new delete ,
. new / delete
.
class Bar : public Foo {
public:
virtual ~Bar(); // Foo::~Foo
void* operator new(size_t bytes);
void operator delete(void* space, size_t bytes);
};
. ,
new delete :
Foo* foo = new Bar;
delete foo;
,
. ++ .
,
.
,
,
: -, .
197
new
new ,
. void* operator
new(size_t), , , .
#define kPoolSize 4096
struct Pool {
unsigned char* next; //
unsigned char space[kPoolSize];
Pool() : next(&space[0]) {}
};
class Foo {
public:
void* operator new(size_t bytes)
{ return ::operator new(bytes); }
void* operator new(size_t bytes, Pool* pool)
{
void* space = pool->next;
pool->next += bytes;
return space;
}
};
void f()
{
Pool localPool;
Foo* foo1 = new Foo; // new
Foo* foo2 = new(&localPool) Foo; //
}
, , .
. , delete , ,
new , ,
new? , :
. ,
.
new ,
, size_t
. , .
new ,
.
(James Coplien),
. new?
class Foo {
public:
void* operator new(size_t, void* p) { return p; }
};
; . ?
?
198
union U {
Foo foo;
Bar bar;
Banana banana;
};
U whatIsThis;
++ , whatIsThis
Foo::Foo(), Bar::Bar() Banana::Banana(). ,
, ,
. ,
; ,
. ,
, , .
.
unsigned char space[4096];
Foo* whatIsThis = new(&space[0]) Foo;
, ++ .
, new . ,
++ , , .
,
new .
new :
1. .
2. .
, ,
.
.
Foo Banana,
Banana new .
Banana* b = new(&space[0]) Banana;
! Foo, Banana. .
.
, :
1. , new, .
2. , !
, Foo Banana , -
Foo.
, delete,
:
1. .
2. delete .
: , .
, , ,
199
. ,
, ,
. ,
, ,
.
void f()
{
Pool localPool;
Foo* foo1 = new Foo; // new
Foo* foo2 = new(&localPool) Foo; //
delete foo1; // new
foo2->~Foo(); //
}
localPool , .
, f() . ,
. ,
. ,
, localPool.
, .
?
; .
,
:
1. .
2. .
3. .
, : ,
. ,
. , ,
.
new
delete.
, .
,
new delete.
, , (
, ).
, , .
++ , .
,
++.
,
new delete .
, .
200
new delete
. ,
.
.
, ,
.
,
, .
.
, ,
. new,
size_t.
, . ,
, .
, . ,
new, ,
. , . ,
, ,
.
( ). , (,
) ,
.
, . ,
.
, ; .
,
.
,
.
, new.
struct Pool { ... }; //
void* operator new(Pool* p); //
template <class Type>
class PoolMP {
private:
Type* pointee;
PoolMP(const PoolMP<Type>&) {} // ...
PoolMP<Type>& operator=(const PoolMP<Type>&)
{ return *this; } // ...
public:
201
PoolMP(Pool* p) : pointee(new(p) Type) {}
~PoolMP() { pointee->~Type(); }
Type* operator->() const { return pointee; }
};
PoolMP
. ,
. ,
, ,
. , ,
.
, ,
new delete .
= , .
, .
template <class Type>
class PoolMP {
private:
Type* pointee;
Pool* pool;
public:
PoolMP(Pool* p) : pointee(new(p) Type), pool(p) {}
~PoolMP() { pointee->Type::~Type(); }
PoolMP(const PoolMP<Type>& pmp) : pointee(new(pool) Type(*pointee)) {}
PoolMP<Type>& operator=(const PoolMP<Type>& pmp)
{
if (this == &pmp) return *this;
delete pointee;
pointee = new(pool) Type(*pointee);
return *this;
}
Type* operator->() const { return pointee; }
};
,
.
. PoolMP ,
. ,
, (, ),
. v-
.
template <class Type>
class MP {
protected:
MP(const MP<Type>&) {} //
MP<Type>& operator=(const MP<Type>&)
{ return *this; } //
MP() {} //
202
public:
virtual ~MP() {} //
virtual Type* operator->() const = 0;
};
,
?
,
.
// foo.h
class Foo {
public:
static Foo* make(); //
static Foo* make(Pool*); //
virtual ~Foo() {}
//
};
// foo.cpp
class PoolFoo : public Foo {
private:
Foo* foo;
Pool* pool;
public:
PoolFoo(Foo* f, Pool* p) : foo(f), pool(p) {}
virtual ~PoolFoo() { foo->~Foo(); }
// , foo
};
class PFoo : public Foo {
//
};
class ConcreteFoo : public Foo { ... };
Foo* Foo::make()
{
return new PFoo(new ConcreteFoo);
}
Foo* Foo::make(Pool* p)
{
return new PoolFoo(new(p) ConcreteFoo, p);
}
. ,
- , make(Pool*).
, .
,
:
Pool
, ..
static Foo::makePool(). make(Pool*)
Pool, makePool() Foo
Pool, Foo (, ).
204
MP ( operator
Type*()),
.
,
=.
// foo.h
//
#include pool.h
class Foo {
private:
Foo(const Foo&) {}
Foo& operator=(const Foo&) { return *this; }
public:
static Pool* makePool(); // , Foo
static Foo* make(); //
static Foo* make(Pool*); //
// ..
};
//
void g(Foo*);
void f()
{
MP<Pool> pool(Foo::makePool());
MP<Foo> foo(Foo::make(pool));
foo->MemberOfFoo(); // operator->()
g(foo); // operator Type*()
// foo, pool
}
, .
g(),
. ,
, ;
.
, ,
++.
14
.
, . ,
, , .
: ,
. ,
.
.
, .
, , ,
.
, , :
. ,
, .
++ :
; , - .
, .
,
.
, ( ).
. Unix,
, .
,
. ,
.
struct Pool {
static Pool* gCurrentPool; //
enum { block_size = 8096 }; //
unsigned char* space; //
size_t remaining; //
206
Pool() : space((unsigned char*)calloc(block_size, \0)),
remaining(block_size) {}
void* Allocate(size_t bytes)
{
if (bytes > block_size)
return ::operator new(bytes); //
if (gCurrentPool == NULL || bytes ? remaining)
gCurrentPool = new Pool;
void* memory = space;
space += bytes;
remaining -= bytes;
return memory;
}
};
class Foo {
public:
void* operator new(size_t bytes)
{
if (Pool::fCurrentPool == NULL)
Pool::gCurrentPool = new Pool;
return Pool::gCurrentPool->Allocate(bytes);
}
void operator delete(void*) {}
};
! ,
. , ++, ,
. ,
, ,
. ,
, .
, ::operator new
calloc(). ++
calloc() ( ),
. ::operator new , ,
,
. ::operator new.
,
,
( ). new delete ,
, .
:
void Eval(Structure s)
{
//
Eval(s.SomePart()); //
//
}
207
, Prolog
.
, .
, Eval(), Eval().
Eval() .
void* operator new(size_t size, Pool* p)
{
return p->Allocate(size);
}
template <class Type>
class PoolP { // ,
private:
Type* pointee;
public:
PoolP(Pool* p) : pointee(new(p) Type) {}
~PoolP { pointee->Type::~Type(); }
//
};
void Eval(Structure s)
{
Pool p; // !
PoolP<Foo> foo(&p); //
Eval(s.SomePart()); //
f(p, s); // f(s); f
// p
}
Pool . , ,
.
PoolP , .
:
PoolP.
(
), . ( !
? ;
++.)
,
new , .
f().
, Eval().
, , ,
.
,
, . ,
-
-, . ++,
.
208
new,
delete ,
.
void* Foo::operator new(size_t bytes)
{
size_t real_bytes = bytes + sizeof(size_t);
unsigned char* space = (unsigned char*)::operator new(real_bytes);
((size_t)space) = real_bytes;
return space + sizeof(size_t);
}
delete ,
. ,
.
. ,
. ,
::operator new (. ).
, ::operator new
calloc , .
, ,
. ? ?
, .
n , n 4.
, 17- , ,
18- 19- . 2,
, , .
(buddy systems),
( ,
) .
.
, 16 2
.
, :
;
(, , );
, .
, ,
. ,
, , .
; delete
. ,
.
209
,
, .
. , ,
.
, .
, , ,
. ,
.
,
. , .
class MemManager {
private:
struct FreeList { //
FreeList* next; // FreeList
void* top_of_list; //
size_t chunk_size; //
FreeList(FreeList* successor, size_t size) : next(successor),
top_of_list(NULL), chunk_size(size) {}
};
FreeList* all_lists; // FreeList
public:
MemManager() : all_lists(NULL) {}
void* Allocate(size_t bytes);
void Deallocate(void* space, size_t bytes);
};
void* MemManager::Allocate(size_t bytes)
{
for (FreeList* fl = all_lists;
fl != NULL && fl->chunk_size != bytes;
fl = fl->next)
{
if (fl->top_of_list != NULL)
{
void* space = fl->top_of_list;
fl->top_of_list = *((void**)(fl->top_of_list));
return space;
}
return ::operator new(bytes); //
}
return ::operator new(bytes); //
}
void MemManager::Deallocate(void* space, size_t bytes)
{
FreeList* fl = NULL;
for (fl = all_lists; fl != NULL; fl = fl->next)
if (fl->chunk_size == bytes) break;
if (fl == NULL) //
{
fl = new FreeList(all_lists, bytes);
all_lists = fl;
210
}
*((void**)space) = fl->top_of_list;
fl->top_of_list = space;
}
Allocate() Deallocate() new delete
. , .
, ,
.
. ,
:
, , 2
.
,
, , .
Flush(),
.
Allocate()
.
,
. 0, . , ?
,
, .
,
. ,
Grab() Release().
class RefCount {
private:
unsigned long count; //
public:
RefCount() : count(0) {}
RefCount(const RefCount&) : count(0) {}
RefCount& operator=(const RefCount&)
{ return *this; } //
virtual ~RefCount() {} //
void Grab() { count++; }
void Release()
{
if (count > 0) count --;
if (count == 0) delete this;
}
};
Grab() Release(),
. , , RefCount,
Grab(). , ,
Release(). 0 ! !
211
. .
RefCount
, RefCount.
template <class Type>
class CP { //
private:
Type* pointee;
public:
CP(Type* p) : pointee(p) { pointee->Grab(); }
CP(const CP<Type>& cp) : pointee(cp.pointee)
{ pointee->Grab(); }
~CP() { ponintee->Release(); }
CP<Type>& operator=(const CP<Type>& cp)
{
if (this == &cp) return *this;
pointee->Release();
pointee = cp.pointee;
pointee->Grab();
return *this;
}
Type* operator->() { return pointee; }
};
, .
Grab().
. ,
. .
class Foo : public RefCount {
private:
Foo(); //
public:
static CP<Foo> make(); //
// Foo
};
, Foo
. : , .
,
RefCount (,
), .
.
template <class Type>
class CMP { //
private:
Type* pointee;
unsigned long count;
212
public:
CMP() : pointee(new Type), count(0) {}
CMP(const CMP<Type>& cmp)
: pointee(new Type(*(cmp.pointee))), count(0) {}
~CMP() { delete pointee; } //
CMP<Type>& operator=(const CMP<Type>& cmp)
{
if (this == &cmp) return *this;
delete pointee;
pointee = new Type(*(cmp.pointee));
return *this;
}
Type* operator->() const { return pointee; }
void Grab() { count++; }
void Release()
{
if (count > 0) count--;
if (count <= 0)
{
delete pointee;
delete this;
}
}
};
,
RefCount. ,
, , .
: (handle) . CMP
, CP RefCount, Grab()
Release() , =.
template <class Type>
class CH { //
private:
CMP<Type>* pointee;
public:
CH(CMP<Type>* p) : pointee(p) { pointee->Grab(); }
CH(const CH<Type>& ch) : pointee(ch.pointee) { pointee->Grab(); }
~CH() { pointee->Release(); }
CH<Type>& operator=(const CH<Type>& ch)
{
if (this == &ch) return *this;
if (pointee == ch.pointee) return *this;
pointee->Release();
pointee = ch.pointee;
pointee->Grab();
return *this;
}
213
CMP<Type> operator->() { return *pointee; }
};
, ,
,
.
; .
. :
( Grab()),
. , . ,
, ,
. , ?
. ,
. A -> B -> C -> D -> A,
. ,
.
. ,
. ,
, , . ,
.
, , :
class A {
private:
Foo* foo;
B* b;
};
, foo, .
A , 0, .
,
,
.
, Grab(), . ,
,
. (strong) (weak)
. CH
, . (
Grab Release) . ,
, ,
.
/, .
, .
. .
, .
( , ) .
, ? .
214
:
, .
, .
Grab Release ,
, .
;
, .
, ,
, .
.
,
.
.
, .
,
, ::operator new
::operator delete.
(memory spaces). ;
-
. ,
, .
:
class MemSpace {
public:
void* Allocate(size_t bytes) = 0;
void Deallocate(void* space, size_t bytes) = 0;
};
( ,
.)
Deallocate() ;
, . ,
MemSpace (
). :
?
, .
,
:
new delete ( ).
new delete .
new .
new .
.
,
.
, :
? ,
215
. , ,
. :
1. . ,
.
2.
(. ).
,
, (,
).
, .
, ?
:
1. , , ,
, .
2. -
(, int). (
v-,
) .
(
) .
, . ,
, 2
.
( 2) .
.
.
.
, - .
, .
, , , .
, .
,
, ,
216
. ,
.
.
, . , ,
, .
, ,
. ,
.
.
15
++: ,
. ,
. !
, .
SmallTalk Lisp
, , ,
. ,
. ++?
: , .
, ,
. ,
.
, .
new delete
: ,
, ( )
(). , ,
, ++
.
++ ,
. , ++ ,
.
, ?
++ .
, ,
. , .
, .
, ,
.
class Foo {
private:
int x;
String y;
218
public:
int& X() { return x; } // x
String* Name() { return &y; } // y
};
Foo ,
( , ,
):
Foo* vtable
x& x
y* y
, v- .
.
, .
.
class A {...}; //
class B {...}; //
class C : public A, public B {...}; //
derived* base* ( base , derived
) , , .
.
C* c = new C;
A* a = c; //
B* b = c; //
cout << c << endl;
cout << a << endl;
cout << b << endl;
, - .
C* A* . C* B*
. ,
( , ,
).
C*, A*
A
B*
B
,
. C* A*,
B C , A.
A*(c)
A
219
v- , C
, A, , ,
A. C*, A,
B C .
,
, B.
B*(c)
B
v- . ,
A C, B
, B. ,
++ (
, ). , ++
:
C* anotherC = C*(void*(B*(c)));
anotherC->MemberOfC();
, ? B*(c) .
void*. C* , C
. void* ,
B* C*. , base* derived* ( base
, derived ) ,
B, C. void* C*,
, .
: ++ ,
, . - ,
-void- ,
. , .
,
, .
, .
class Base {...};
class A : virtual public Base {...};
class B : virtual public Base {...};
class Foo : public A, public B {...};
. , Base ,
, Foo. A B Base ,
, , .
, , .
Foo
Base
220
,
,
.
, .
class Foo {
private:
int x;
public:
static int& Foo::*X() { return &Foo::x; }
};
Foo f = new Foo; //
int& Foo::*pm = Foo::X(); // int
int& i = f->*pm; //
X() int, int Foo.
Foo::X() , ,
. return &Foo::x; , x.
int& Foo::*pm = Foo::X(); pm,
int Foo. , Foo::X(). , int&
i = f->*pm;
int. : pm ,
.
int& int*.
,
.
, , .
.
f vtable
pm = Foo::X()
F->*pm x
.
, ,
, , . ,
,
.
, ,
, .
, , .
? , . ,
, .
, .
, ,
. ,
221
( ). *-
,
. P H
, , P
.
, ,
. P
, .
template <class Type>
class P { //
private:
Type* pointee;
public:
void* operator new(size_t); //
//
void operator delete(void*); //
//
//
};
template <class Type>
class H { //
private:
P<Type>* ptr;
public:
//
};
class Foo {
private:
P<Bar>& bar; // Bar
//
H<Bar>& bar; // Bar
};
, , ,
- .
. , , ,
, new delete P.
,
. ( ),
.
.
.
template <class Type>
class P {
private:
static P<Type>* head; // MP
static P<Type>* tail; //
P<Type>* next; //
P<Type>* previous; //
Type* pointee;
222
public:
P(); // this
P(const P<Type>& p); // this
~P(); // this
P<Type>& operator=(const P<Type>& p); // ,
// p.pointee
//
};
=, . ,
; .
class Foo {
private:
P<Bar> bar; //
};
Foo P,
bar . Foo P,
bar . ,
. , ,
.
.
, .
class Foo {
private:
Bar* bar;
};
, , -
Bar* Foo. , ,
( , ,
),
. , bar , ,
Bar - , Bar.
, Bar.
, ,
: .
. ,
, .
, . ,
. ,
, ,
. ,
, ,
. this,
, , .
,
.
223
,
++, -
.
class Foo {
private:
H<Bar> bar; // Bar
public:
H<Bar> GetBar() { return bar; }
};
H ( , ).
H<Bar> Bar. ,
( GetBar()), .
( , ) ,
.
. ,
.
:
,
VoidPtr .
, .
,
.
,
1 0. ,
, , ( )
.
.
. ,
, ,
. .
.
, , , .
.
,
.
.
:
1. .
2. .
3. .
( )
.
.
224
VoidPtr
, .
class VoidPtrPool; // ,
// VoidPtr
class VoidPtr {
friend class VoidPtrPool;
private:
unsigned long refcount; //
protected:
void* address; //
size_t size; //
VoidPtr() : address(NULL), size(0), refcount(0) {}
VoidPtr(void* adr, size_t s) : address(adr), size(s), refcount(0) {}
public:
static VoidPtrPool* pool;
virtual ~VoidPtr() { size = 0; address = NULL; }
void* operator new(size_t)
{
if (pool == NULL)
pool = new VoidPtrPool;
return pool->Allocate();
}
void operator delete(void* space)
{ pool->Deallocate((VoidPtr*)space); }
void Grab() { refcount++; }
void Release()
{
if (refcount > 0) refcount--;
if (refcount <= 0) delete this;
}
};
, VoidPtr.
, -> , ,
.
. ,
. ,
. ,
. ,
.
template <class Type>
class MP : public VoidPtr {
private: //
MP(const MP<Type>&) {}
MP<Type>& operator=(const MP<Type>&) { return this; }
public:
MP() : VoidPtr(new Type, sizeof(Type)) {}
virtual ~MP() { ((Type*)address)->Type::~TypeOf(); }
225
Type* operator->() { return (Type*)address; }
};
.
template <class Type>
class Handle {
private:
MP<Type>* pointer;
public:
Handle() : pointer(new MP<Type>) { pointer->Grab(); }
Handle(const Handle<Type>& h) : pointer(h.pointer)
{ pointer->Grab(); }
Handle<Type>& operator=(const Handle<Type>& h)
{
if (this == &h) return *this;
if (pointer == h.pointer) return *this;
pointer->Release();
h.pointer->Grab();
return *this;
}
MP<Type>& operator->() { return *pointer; }
};
, .
class Bar {
private:
H<Foo> foo;
public:
void f();
};
void Bar::f()
{
Handle<Foo> f; // Foo* f = new Foo;
f = foo; // operator=(Handle<Type>(foo));
foo = f; // H<Type>(f)
}
, , VoidPtr,
VoidPtr; , . ;
VoidPtrPool VoidPtr.
VoidPtrBlock.
struct VoidPtrBlock {
VoidPtrBlock* next; //
VoidPtr slots[BLOCKSIZE]; //
VoidPtrBlock(VoidPtrBlock* next_in_list) : next(next_in_list)
{
//
for (int i = 0; i < BLOCKSIZE - 1; i++)
226
slots[i].address = &slots[i + 1];
slots[BLOCKSIZE - 1].address = NULL;
}
~VoidPtrBlock() { delete next; }
}
class VoidPtrPool {
private:
VoidPtr* free_list; // VoidPtr
VoidPtrBlock* block_size; //
public:
VoidPtrPool() : block_list(NULL), free_list(NULL) {}
~VoidPtrPool() { delete block_list; }
VoidPtr* Allocate();
void Deallocate(VoidPtr* vp);
};
VoidPtr* VoidPtrPool::Allocate()
{
if (free_list == NULL) //
{
block_list = new VoidPtrBlock(block_list);
//
block_list->slots[BLOCKSIZE 1].address = free_list;
free_list = &block_list->slots[0];
}
VoidPtr* space = (VoidPtr*)free_list;
free_list = (VoidPtr*)space->address;
return space;
}
void VoidPtrPool::Deallocate(VoidPtr* p)
{
vp->address = free_list;
free_list = (VoidPtr*)vp->address;
vp->size = 0;
}
, .
. ,
, ,
, .
VoidPtrIterator.
VoidPtrPool , ( ,
). ,
,
.
class VoidPtrIterator {
protected:
VoidPtrIterator() {}
public:
virtual bool More() = 0;
227
virtual VoidPtr* Next() = 0;
};
.
size.
class VoidPtrPoolIterator : public VoidPtrIterator {
private:
VoidPtrBlock* block;
int slot; //
virtual void Advance() //
{
while (block != NULL)
{
if (slot >= BLOCKSIZE)
{
block = block->next;
slot = 0;
}
else if (block->slots[slot].size != 0)
break;
slot++;
}
}
public:
VoidPtrPoolIterator(VoidPtrBlock* vpb)
: block(vpb), slot(0), { Advance(); }
virtual bool More() { return block != NULL; }
virtual VoidPtr* Next()
{
VoidPtr* vp = &block->slots[slot];
Advance();
return vp;
}
};
, VoidPtrPool :
VoidPtrIterator* iterator()
{ return new VoidPtrPoolIterator(this); }
, VoidPtrPoolIterator VoidPtr,
size. , , 16
; Advance() ,
.
size, .
, .
,
. ,
++ .
228
,
VoidPtr .
, , .
, (,
).
class Foo {
public:
static Foo* make(); // -
virtual void Member1() = 0;
// ..
};
// foo.cpp
class FooPtr : public Foo, public VoidPtr {
public:
FooPtr(Foo* foo, size_t size) : VoidPtr(foo, size) {}
virtual ~FooPtr() { delete (Foo*)address; }
virtual void Member1()
{ ((Foo*)address)->Member1(); }
// ..
};
class RealFoo : public Foo { ... };
Foo* Foo::make()
{
return new FooPtr(new RealFoo, sizeof(RealFoo));
}
//
class Bar {
private:
Foo* foo; //
public:
Bar() : foo(Foo::make()) {}
};
. ,
, ,
.
, VoidPtrPool
FooPtr. , - VoidPtr
, , v-.
, -,
, , .
,
.
, ,
. void* VoidPtr CommonBase* ( CommonBase
). size, ,
VoidPtr, VoidPtr, 4- v-
. , v-
, .
229
, .
, ,
:
void f(int);
class Foo {
private:
int x; // ,
public:
void F() { f(x); }
};
, ? , f()
:
void f(int&);
.
: ,
, , .
class Bar {
private:
Foo foo;
};
, , Bar foo.
, Foo .
. ,
, .
( , )
. .
(Bakers Algorithm).
, A B.
( ). ,
.
.
.
, (
VoidPtr).
. HalfSpace
, Space , .
HalfSpace
Allocate(). Deallocate() .
class HalfSpace {
private:
unsigned long next_byte; //
unsigned char bytes[HALFSIZE];
public:
230
HalfSpace() : next_byte(0) {}
void* Allocate(size_t size);
void Reinitialize() { next_byte = 0; }
};
void* HalfSpace::Allocate(size_t size)
{
//
size = ROUNDUP(size);
if (next_byte + size >= HALFSIZE)
return NULL; //
void* space = &bytes[next_byte];
next_byte += size;
return space;
}
Space
. Allocate(),
.
,
Swap().
VoidPtr .
class Space {
private:
HalfSpace A, B;
HalfSpace* active;
HalfSpace* inactive;
void Swap(); // ,
public:
Space() : active(&A), inactive(&B) {};
void* Allocate(size_t size);
};
void* Space::Allocate(size_t size)
{
void* space = active->Allocate(size);
if (space != NULL) return space;
Swap();
Space = active->Allocate(size);
if (space == NULL)
//
return space;
}
void Space::Swap()
{
if (active == &A)
{
active = &B;
inactive = &A;
}
else
231
{
active = &A;
inactive = &B;
}
active->Reinitialize();
// VoidPtr
VoidPtrIterator* iterator = VoidPtr::pool->iterator();
while (iterator->More())
{
VoidPtr* vp = iterator->Next();
if (vp->address >= inactive &&
vp->address < inactive + sizeof(*inactive))
{
void* new_space = active->Allocate(vp->size);
if (new_space == NULL)
//
memcpy(new_space, vp->address, vp->size);
vp->address = new_space;
}
}
delete iterator;
}
while Space::Swap().
, . ,
, .
new
, new, .
void* operator new(size_t size, Space* space)
{
return space->Allocate(size);
}
, .
template <class Type>
class BMP : public VoidPtr {
private: //
BMP(const MP<Type>&) {}
BMP<Type>& operator=(const BMP<Type>&) { return *this; }
public:
BMP() : VoidPtr(new(object_space) Type, sizeof(Type)) {}
virtual ~BMP() { ((Type*)address->Type::~Type(); }
Type* operator->() { return (Type*)address; }
};
object_space ( ,
VoidPtr), Space.
232
Swap() , ,
. ,
, . ,
, .
- - .
.
, . , -
. ,
.
Space. Swap() ,
,
.
class Space {
private:
VoidPtrIterator* iterator; //
HalfSpace A, B;
HalfSpace* active;
HalfSpace* inactive;
void Swap(); // ,
public:
Space() : active(&A), inactive(&B), iterator(NULL) { Swap(); }
void* Allocate(size_t size);
void Copy1();
};
void* Space::Allocate(size_t size)
{
void* space = active->Allocate(size);
if (space != NULL)
//
return space;
}
void Space::Swap()
{
if (active == &A)
{
active = &B;
inactive = &A;
}
else
{
active = &A;
inactive = &B;
}
active->Reinitialize();
delete iterator;
iterator = VoidPtr::pool->iterator();
}
void Space::Copy1()
233
{
if (!iterator->More())
Swap(); //
else
{
VoidPtr* vp = iterator->Next();
if (vp->address >= inactive &&
vp->address < inactive + sizeof(*inactive))
{
void* new_space = active->Allocate(size);
if (new_space == NULL)
throw(OutOfMemory());
memcpy(new_space, vp->address, vp->size);
vp->address = new_space;
}
}
}
Copy1() ,
. ,
, .
, ,
.
, ,
, . ,
!
SystemCall(&aString); // aString ,
//
, , ,
. , ,
. , ,
. ;
, - .
,
.
class Space {
public:
void Externalize(VoidPtr* vp)
{
void* space = ::operator new(vp->size);
memcpy(space, vp->address, vp->size);
vp->address = space;
}
void Internalize(VoidPtr* vp)
{
void* space = Allocate(vp->size);
memcpy(space, vp->address, vp->size);
::operator delete(vp->address);
vp->address = space;
234
}
}
Externalize() ; Internalize()
. Copy1() ,
.
this (. )
. ,
,
.
, ,
,
.
: C++
.
++ ,
- . ,
, .
this
Copy1() this, , ,
. this
.
. , , 180
. , , ,
, Copy1()
:
class Foo {
public:
void Fn()
{
// ,
VoidPtr::pool->Copy1();
}
};
, , Fn(),
this Fn(). , ,
, 2435 ,
, .
, Copy1()
. , Copy1()
. ,
(inside-out), , -
(operational object) .
.
class Operation {
friend void MainLoop();
private:
static Queue<Operation> OperationQ;
public:
virtual void DoSomething() = 0;
void Post() { OperationQ.Push(this); }
235
};
void MainLoop()
{
Operation* op;
while ((op = Operation::OperationQ.Pop()) != NULL)
{
op->DoSomething();
object_space->Copy1();
}
}
- , ,
, Operation, . ,
Operation DoSomething()
.
:
// -
void Foo::SomeOperation()
{
for (...)
OnePass();
}
, :
Foo::SomeOperation(), ,
; Copy1()
Foo::SomeOperation(), .
:
//
class FooSomeOperation : public Operation }
public:
virtual void DoSomething();
{
//
if ( )
this->Post(); //
delete this;
}
};
void Foo::SomeOperation()
{
Operation* op = new FooSomeOperation(args);
op->Post();
// op->DoSomething
}
Copy1()
FooSomeOperation::DoSomething(). ,
- .
(,
),
.
236
,
, . ,
.
, ,
. , , , .
, Copy1(),
.
this. , this
,
this, . , ,
, this .
, ( )
,
. -,
, .
.
,
.
. ,
(compaction in place). ,
.
.
, ,
. :
.
, ,
,
. ,
. VoidPtr
.
VoidPtr
. VoidPtr
,
237
. (. )
VoidPtrPool::tail. . VoidPtr
. VoidPtr.
class VoidPtr {
private:
//
VoidPtr* next; //
VoidPtr* previous; //
protected:
//
VoidPtr() : address(NULL), size(0), refcount(0),
next(NULL), previous(NULL) {}
VoidPtr(void* addr, size_t s) : address(addr), size(s), refcount(0),
next(NULL), previous(pool->tail->previous)
{
pool->tail->next = this;
pool->tail = this;
}
public:
//
virtual ~VoidPtr()
{
if (size != 0) //
{
if (previous != NULL)
previous->next = next;
if (next != NULL)
next->previous = previous;
if (pool->tail == this)
pool->tail = previous;
}
size = 0;
address = NULL;
}
};
VoidPtrPool .
class VoidPtrPool { // ,
friend class VoidPtr; // tail
private:
//
VoidPtr head; // VoidPtr,
//
VoidPtr* tail; //
public:
//
VoidPtrPool() : block_list(NULL), free_list(NULL), tail(&head) {}
};
238
VoidPtrPool , ,
VoidPtr.
.
, .
class VoidPtrPoolIterator : public VoidPtrIterator {
private:
VoidPtr* next;
public:
VoidPtrIterator(VoidPtr* first) : next(first) {}
virtual bool More() { return next != NULL; }
virtual VoidPtr* Next()
{
VoidPtr* vp = next;
next = next->next;
return vp;
}
};
VoidPtrIterator* VoidPtrPool::iterator()
{
return new VoidPtrPoolIterator(&head.next);
}
, .
class Space {
private:
unsigned long next_byte;
unsigned char bytes[SPACESIZE];
public:
Space() : next_byte(0) {}
void* Allocate(size_t size);
void Compact();
};
void* Space::Allocate(size_t size)
{
//
size = ROUNDUP(size);
if (next_byte + size > SPACESIZE)
{
Compact();
if (next_byte + size > SPACESIZE)
//
}
void* space = &bytes[next_byte];
next_byte += size;
return space;
}
239
void Space::Compact()
{
next_byte = 0;
VoidPtrIterator* iterator = VoidPtrPool::iterator();
while (iterator->More())
{
VoidPtr* vp = iterator->Next();
void* space = Allocate(vp->size);
if (space < vp->address) // ,
}
delete iterator;
}
.
,
. VoidPtr ,
. VoidPtr*
. VoidPtr ,
; , .
, . ,
, - .
, . ,
, , .
. ,
, .
. , .
. : VoidPtrIterator Space
, Copy1().
, .
, VoidPtr .
, 8.
, ,
. , VoidPtr,
,
.
, .
.
++ ,
.
, ,
, . ,
, ++
.
240
. ,
.
, ++, ,
.
16
.
. , ,
. , -
++ , .
++.
, , , .
: ?
. ,
.
, ,
. ,
.
++ - ,
. ,
.
void f()
{
Foo* foo = new Foo; // foo
}
( )
:
this , .
(*) (&) .
.
, .
, . , this
Bar*, Bar this.
,
,
.
242
class String {
private:
char* str;
public:
operator char*() { return str; }
};
strcpy(aString, bString); // char*
strcpy(char*, char*) .
strcpy strcpy,
. , strcpy
. , , , -
(callback). ,
, !
. ,
.
template <class Type>
class Array {
public:
Type* operator[] (LargeInt);
};
, , , ,
. ,
; - , ,
X? , X ,
. .
.
,
: , .
. ,
.
,
.
.
.
void Foo::f(Bar* b)
{
b->member_of_Bar();
}
++ , .
,
.
243
,
. , , .
.
, .
.. ,
. ,
/.
SmallTalk
. ++ . (. ) ,
,
.
,
.
,
.
, ,
.
.
class Foo {
private:
Bar* bar;
};
class PFoo { // Foo
private:
Foo* foo;
public:
FunctionThatEnumeratesPointersInFoo();
};
? ,
, . , PFoo , , foo
Foo*, bar? , Bar, -
? Bar
,
.
class Bar {
};
class Pbar { // Bar
};
class Foo {
private:
Pbar bar;
};
244
class PFoo { // Foo
private:
Foo* foo;
public:
FunctionThatEnumeratesPointersInFoo();
};
, PFoo, , PBar.
, .
, (ingenious), ,
, .
,
.
: ,
.
: ,
, , ,
.
class Functor { //
public:
virtual void Apply(MotherOfAllClasses*) = 0;
};
class MotherOfAllClasses {
public:
// fn
virtual void EachObject(Functor& fn);
};
EachObject() fn.Apply(this), EachObject()
, . ,
EachObject() Base::EachObject() ,
.
MotherOfAllClasses , ,
. , , .
( ), ,
.
class MOAOIterator { // MotherOfAllObjectsIterator
public:
virtual bool More() = 0;
virtual MotherOfAllObjects* Next() = 0;
};
class MotherOfAllObjects {
public:
virtual MOAOIterator* EachObject();
};
245
, ,
. ,
: .
. , , .
.
, , , ?
, ,
50 ?
.
, ,
.
,
. , :
, . ,
0, , , .
. VoidPtr
, : VoidPtr::Release()
. : ,
, , .
.
template <class Type>
class WH {
friend class Handle<Type>;
private:
BMP<Type>* pointer;
WH() : pointer(new BMP<Type> (new(object_space) Type)) {};
BMP<Type>& operator->() { return *pointer; }
};
, .
class Foo {
private:
WH<Bar> bar; // Bar + MP<Bar>
};
, ,
.
template <class Type>
class SH {
private:
BMP<Type>* pointer;
public:
SH() : pointer(new BMP<Type>(new Type)) { pointer->Grab(); }
SH(const SH<Type>& h) : pointer(h.pointer) { pointer->Grab(); }
246
SH(const WH<Type>& h) : pointer(h.pointer) { pointer->Grab(); }
operator WH<Type>() { return WH<Type>(pointer); }
SH<Type>& operator=(const SH<Type>& h)
{
if (this == &h) return *this;
if (pointer == h.pointer) return *this;
pointer->Release();
h.pointer->Grab();
return *this;
}
BMP<Type>& operator->() { return *pointer; }
};
( ),
. , H<Type>, operator
H<Type>() ,
.
class Bar {
private:
WH<Foo> foo;
public:
void f();
};
void Bar::f()
{
SH<Foo> f; // Foo* f = new Foo;
f = foo; // operator=(SH<Type>(foo));
foo = f; // operator WH<Type>(f);
}
VoidPtrIterator? VoidPtrPool
. ,
-. ,
. : .
, ,
, .
,
, .
.
/.
VoidPtrIterator.
class VoidPtrIterator {
protected:
VoidPtrIterator() {}
public:
virtual bool More() = 0;
virtual VoidPtr* Next() = 0;
};
. ,
( ).
247
, . VoidPtrPool::iterator() 15
:
// VoidPtrPool
class VoidPtrPool {
public:
VoidPtrIterator* Reachable()
{ return new ReachableIterator(this); }
VoidPtrIterator* InRange(void* low, void* high)
{ return new RangeIterator(this); }
};
, ,
( ). , VoidPtrPoolIterator
Advance() .
VoidPtrPoolIterator.
class ReachableIterator : public VoidPtrPoolIterator {
protected:
virtual void Advance() //
{
do
VoidPtrPoolIterator::Advance();
while (block != NULL && block->slots[slot].refcount == 0);
}
public:
ReachableIterator(VoidPtrBlock* vpb) : VoidPtrPoolIterator(vpb) {}
};
,
. .
, VoidPtrPoolIterator.
class InRange : public VoidPtrPoolIterator {
private:
void* low; //
void* high; //
virtual void Advance() //
{
do
VoidPtrPoolIterator::Advance();
while (block != NULL &&
(block->slots[slot].address < low ||
block->slots[slot].address >= high));
}
public:
InRange(VoidPtrBlock* vpb, void* low_addr, void* high_addr)
: VoidPtrPoolIterator(vpb), low(low_addr), high(high_addr) {}
};
248
VoidPtrIterator, ,
. .
.
class MotherOfAllObject { //
public:
virtual VoidPtrIterator* Pointers() = 0;
};
template <class Type>
class VoidPtrArrayIterator : public VoidPtrIterator {
private:
VoidPtr* ptrs[Entries];
int next; //
public:
VoidPtrArrayIterator() : next(0)
{
for (int i = 0; i < Entries; i++)
ptrs[i] = NULL;
}
VoidPtr*& operator[](uint slot) { return ptrs[slot]; }
virtual bool More() { return next < Entries; }
virtual VoidPtr* Next() { return ptrs[next++]; }
};
//
class Foo {
private:
WH<Bar> bar;
public:
virtual VoidPtrIterator* Pointers()
{
new VoidPtrArrayIterator<1>* iterator = new VoidPtrArrayIterato<1>;
iterator[0] = bar.Pointer();
return iterator;
}
};
VoidPtrArrayIterator ,
. ,
, VoidPtr* NULL.
Foo::Pointers() VoidPtrArrayIterator.
, WH<Widget>
iterator(index++) = widget.Pointer().
,
. Foo ,
.
. ,
,
.
, , ,
249
. , ,
.
Space , .
, .
, Scavenge(),
. , Stack.
template <class Type>
class Stack {
public:
Push(Type*);
Type* Pop(); // NULL
};
class Space {
private:
VoidPtrIterator* iterator; //
Stack<VoidPtrIterator> iterator_stack;
HalfSpace A, B;
HalfSpace* active;
HalfSpace* inactive;
void Scavenge(); //
void Swap(); //
public:
Space() : active(&a), inactive(&B), iterator(NULL) { Swap(); }
void* Allocate(size_t size)
{
void* space = active->Allocate(size);
if (space == NULL) throw(OutOfMemory());
return space;
}
void Copy1();
};
Scavenge(), Swap() Copy1() .
Scavenge
Scavenge() .
, . .
, , , .
void Space::Scanvege()
{
VoidPtrIterator* vpi =
VoidPtr::pool->InRange(inactive, inactive + sizeof(*inactive));
while (vpi->More()) {
VoidPtr* vp = vpi->Next();
delete vp; //
}
delete vpi;
}
250
Swap
Swap() . Scavenge()
, ,
Copy1() .
void Space::Swap()
{
Scavenge(); //
if (active == &A)
{
active = &B;
inactive = &A;
}
else
{
active = &A;
inactive = &B;
}
active->Reinitialize();
iterator = VoidPtr::pool->iterator();
}
Copy1
Copy1() . ,
. , ,
, , .
void Space::Copy1()
{
if (!iterator->More())
{
// ,
delete iterator;
iterator = iterator_stack.Pop();
if (iterator == NULL) // !
Swap(); //
}
else
{
VoidPtr* vp = iterator->Next();
if (vp->address >= &inactive &&
vp->address < &inactive + sizeof(*insactive))
{
//
void* new_space = active->Allocate(vp->size);
if (new_space == NULL)
//
memcpy(new_space, vp->address, vp->size);
vp->address = new_space;
iterator_stack.Push(iterator);
iterator = vp->address->Pointers();
251
}
//
}
}
Scavenge().
:
1. Scavenge() , .
Copy1(),
.
2.
VoidPtrPool .
.
, .
,
.
, ,
. .
, .
, . ,
, /.
:
1.
, .
2.
.
3. Copy1() , ,
, .
,
, .
.
.
,
, .
. :
.
,
. , VoidPtr :
1. VoidPtr, .
2. VoidPtr ; ,
.
252
3. VoidPtr VoidPtr, ,
. ,
.
4. 3, .
5. VoidPtr, ; ,
.
, , .
6. , VoidPtr
.
, , .
, , , . ,
, , .
.
?
, ?
. , (
)? , ;
, . ,
- ,
. , . .
, ? ,
, ,
. , .
, , ,
( ,
). ,
, ++. ,
,
.
,
( ).
, ,
. , ,
.
, (Mother Of All Objects, MOAO).
VoidPtr,
void*& MOAO*&. ,
? , - ,
. , ( ++) ,
- , ,
, . , ,
. , ++
SmallTalk, .
,
,
. - ,
.
253
, , :
1. .
2. .
3. .
4. .
, .
, - :
1. . - ,
?
2. . ?
3. .
?
,
:
;
;
.
. ,
. , ,
2, .
;
.
, .
?
( ) ?
, , (
, ).
?
, , .
.
, ,
.
, .
?
, , ,
.
, .
N 2M ,
N-M . , N=20 (
), M=4 ( 16 ), 16 .
254
,
, .
,
:
class Foo {
private:
Bar* bar;
};
Foo* f = new Foo;
, , (
this?) . ,
, , , . .
, ,
. .
, .
, , ,
( ).
, . ,
,
. (pointer aliasing).
, .
,
.
, . ,
.
, , .
. ,
, .
, .
,
.
: .
,
. ,
,
.
.
. , ,
255
, .
, , ,
.
,
, ,
. , ,
, .
( ),
.
, . ?
, ,
.
,
. , RISC-
: .
.
, ,
( , ?).
, int char*; ,
v-! , ++ - Lisp SmallTalk.
,
. , ,
++, .
, ++ , .
, ,
. -
?
-, ++
. ,
. ,
, ,
.
-, :
. ,
. , , ,
++ , .
, .
-, ++. ,
, : , 95-
++, :
!
Java C++
, Java, :
, ,
? , ,
Java ++. ,
, ++, ?
Java ++. - Java ++,
. , Java,
. , Java ,
. .
, ++ ,
Java- .
Java ( 1),
.
1
int* pt = new int;
delete pt;
Java (. 2). Java
, , ++. Java
++.
-
.
2
char* na = Bob Smith
na++;
Java
.
, Java ,
++. , int Java 32-
(. 1). Java -,
.
258
1. Java
int 4
short 2
long 8
float 4
double 8
, . Java
, (. 3) .
Java ++.
3
struct name {
char fname[20];
char lname[30];
}
Java ,
++. (=),
(==). 4 ++,
Java.
4
if (value = 10)
Java? .
Java ++ , Java -
. , Java ,
, .
Java! ++.
Java ++. , Java ( main)
. Java main -
(. 5). Java , , main ,
5
public class ShellClass
{
public static void main(Strings[] args)
{
}
}
Java . ++ ,
. Java . Java
char*. Java ,
. ,
.
Java ++, . , Java
. Java ,
259
. ,
, - Java .
Java . , Java
++ (. 6). Java , ,
, .
6
// Java
MyObject ob1;
// C++
MyObject* ob1;
Java . , ++, .
, 7, ++, Java.
, , (inline) .
7
class Person
{
};
void Person::Raise()
{
salary *= 1000
}
++ Java? . Java
Internet, . Java
, TCP/IP, HTTP FTP.
URL , .
Java , Java-
. Internet-. Java
++,
. ,
Java.
, Java .
, Java
,
.
Java ? ++?
++. Internet,
Java , ++. ,
Java
, .