. C++ 3rd: --------------------------------------------------------------- © Copyright , 2000 , 12 Oct 2004 Origin: http://ders.stml.net/cpp/ http://ders.stml.net/cpp/ ---------------------------------------------------------------
43 | 1.3.1. |
73 | 2.5.5. |
79 | 2.7.2. |
128 | 5.1.1. |
192 | 7.4. |
199 | 7.6. |
202 | 7.7. |
296 | 10.4.6.2. - |
297 | 10.4.7. |
316 | 11.3.1. - - |
328 | 11.5.1. |
333 | 11.7.1. |
337 | 11.9. |
344 | 11.12. String |
351 | 12.2. |
361 | 12.2.6. |
382 | 13.2.3. |
399 | 13.6.2. - |
419 | 14.4.1. |
421 | 14.4.2. auto_ptr |
422 | 14.4.4. new |
431 | 14.6.1. |
431 | 14.6.3. |
460 | 15.3.2. |
461 | 15.3.2.1. |
475 | 15.5. |
477 | 15.6. |
478 | 15.6. |
479 | 15.6.1. |
480 | 15.6.2. " " |
498 | 16.2.3. STL- |
505 | 16.3.4. |
508 | 16.3.5. |
526 | 17.1.4.1. |
541 | 17.4.1.2. |
543 | 17.4.1.3. |
555 | 17.5.3.3. |
556 | 17.6. |
583 | 18.4.4.1. |
584 | 18.4.4.2. - |
592 | 18.6. , |
592 | 18.6.1. |
622 | 19.2.5. |
634 | 19.4.1. |
637 | 19.4.2. , |
641 | 19.4.4. |
647 | 20.2.1. |
652 | 20.3.4. |
655 | 20.3.6. |
676 | 21.2.2. |
687 | 21.3.4. |
701 | 21.4.6.3. , |
711 | 21.6.2. |
773 | 23.4.3.1. 1: |
879 | .5. |
931 | B.13.2. |
935 | B.13.6. template |
( ) C++ 3rd , , . - , , .
. , " C++" , .. , C++. C++ 3rd, C++. , () , , .
- , : Bjarne Stroustrup "The C++ Programming language", 3rd edition / C++ (ISO/IEC 14882 Programming languages - C++, First edition, 1998-09-01). , , C++ . , , C++ Standard Core Issues List C++ Standard Library Issues List .
STL, . , , .
, "The C programming Language" by Brian W. Kernighan and Dennis M. Ritchie, 2 , -- !
, .
new
, delete
, type_id
, dynamic_cast
, throw
try
, C++ .
, , " ". / () , / , / , , .
#include <stdio.h> #include <stdlib.h> #include <time.h> struct A { A(); ~A(); }; void ACon(); void ADes(); void f1() { A a; } void f2() { ACon(); ADes(); } long Var, Count; A::A() { Var++; } A::~A() { Var++; } void ACon() { Var++; } void ADes() { Var++; } int main(int argc,char** argv) { if (argc>1) Count=atol(argv[1]); clock_t c1,c2; { c1=clock(); for (long i=0; i<Count; i++) for (long j=0; j<1000000; j++) f1(); c2=clock(); printf("f1(): %ld mlns calls per %.1f sec\n",Count,double(c2-c1)/CLK_TCK); } { c1=clock(); for (long i=0; i<Count; i++) for (long j=0; j<1000000; j++) f2(); c2=clock(); printf("f2(): %ld mlns calls per %.1f sec\n",Count,double(c2-c1)/CLK_TCK); } }
f1()
f2()
, , A
, ACon()
ADes()
.
-- . , f1()
f2()
.
; , 10 !
inline
? :
struct A { A() { Var++; } ~A() { Var++; } }; void f1() { A a; } void f2() { Var++; Var++; }
f1()
f2()
. , .
? abstraction penalty, .. (-) .
abstraction penalty .
void f1() { A a; }
void f1() // { A::A(); A::~A(); }:
void f2() { ACon(); ADes(); }-- ! , :
void f1() { A a; f(); } void f2() { ACon(); f(); ADes(); }, ? -- , ..
f1()
void f1() // { A::A(); try { f(); } catch (...) { A::~A(); throw; } A::~A(); }.. , , . .. , , .
f1()
(, "" /):
void f1() // { A::A(); try { // } catch (...) { A::~A(); throw; } A::~A(); }, , " ", . ,
inline
. STL, , , .
abstraction penalty -- " ".
vtbl
.
, .. "" vtbl
.
. (.. ) B1
:
struct B1 { // struct int a1; int b1; virtual ~B1() { } };
vptr
( ) . B1
:
vptr_1 // vtbl B1 a1 // b1
B2
D
struct D: B1, B2 { virtual ~D() { } };:
vptr_d1 // vtbl D, B1 vptr_1 a1 // B1 b1 vptr_d2 // vtbl D, B2 vptr_2 a2 // B2 b2
vptr
? , , .
, , , : " "? , . , . .. :
D d; B2* ptr=&d;
ptr
vptr_d2
. vptr
D
vptr_d1
. , , . ? B1
B2
vtbl
, D
. .. vtbl
D
: B1
, B2
.
, , , .
, , , : vptr
this
vtbl
. , .
, .
#include <stdio.h> #include <stdlib.h> #include <time.h> struct B { void f(); virtual void vf(); }; struct D : B { void vf(); // B::vf }; void f1(B* ptr) { ptr->f(); } void f2(B* ptr) { ptr->vf(); } long Var, Count; void B::f() { Var++; } void B::vf() { } void D::vf() { Var++; } int main(int argc,char** argv) { if (argc>1) Count=atol(argv[1]); clock_t c1,c2; D d; { c1=clock(); for (long i=0; i<Count; i++) for (long j=0; j<1000000; j++) f1(&d); c2=clock(); printf("f1(): %ld mlns calls per %.1f sec\n",Count,double(c2-c1)/CLK_TCK); } { c1=clock(); for (long i=0; i<Count; i++) for (long j=0; j<1000000; j++) f2(&d); c2=clock(); printf("f2(): %ld mlns calls per %.1f sec\n",Count,double(c2-c1)/CLK_TCK); } }, 10% 2.5 . .. , "" .
"" , .. ( )
#include <stdio.h> #include <stdlib.h> #include <time.h> struct B { int ackf(int x, int y); virtual int vackf(int x, int y); }; struct D : B { int vackf(int x, int y); // B::vackf }; void f1(B* ptr) { ptr->ackf(3, 5); // 42438 ! } void f2(B* ptr) { ptr->vackf(3, 5); // 42438 ! } int B::ackf(int x, int y) { if (x==0) return y+1; else if (y==0) return ackf(x-1, 1); else return ackf(x-1, ackf(x, y-1)); } int B::vackf(int x, int y) { return 0; } int D::vackf(int x, int y) { if (x==0) return y+1; else if (y==0) return vackf(x-1, 1); else return vackf(x-1, vackf(x, y-1)); } long Count; int main(int argc,char** argv) { if (argc>1) Count=atol(argv[1]); clock_t c1,c2; D d; { c1=clock(); for (long i=0; i<Count; i++) for (long j=0; j<1000; j++) f1(&d); c2=clock(); printf("f1(): %ld ths calls per %.1f sec\n", Count, double(c2-c1)/CLK_TCK); } { c1=clock(); for (long i=0; i<Count; i++) for (long j=0; j<1000; j++) f2(&d); c2=clock(); printf("f2(): %ld ths calls per %.1f sec\n", Count, double(c2-c1)/CLK_TCK); } }, .
char vc1[200]; char vc2[500]; void f() { copy(&vc1[0],&vc1[200],&vc2[0]); }
, , . - :
The issue is whether taking the address of one-past-the-last element of an array is conforming C and C++. I could make the example clearly conforming by a simple rewrite:copy(vc1,vc1+200,vc2);However, I don't want to introduce addition to pointers at this point of the book. It is a surprise to most experienced C and C++ programmers that&vc1[200]
isn't completely equivalent tovc1+200
. In fact, it was a surprise to the C committee also and I expect it to be fixed in the upcoming revision of the standard. (also resolved for C9x - bs 10/13/98)., C C++ , . :
copy(vc1,vc1+200,vc2);, . C C++ ,&vc1[200]
vc1+200
. , C , , .
? C++ :
&vc1[200] -> &(*((vc1)+(200))) -> &*(vc1+200)
&*(vc1+200) == vc1+200
?
It is false in C89 and C++, but not in K&R C or C9x. The C89 standard simply said that&*(vc1+200)
means dereferencevc1+200
(which is an error) and then take the address of the result, and the C++ standard copiled the C89 wording. K&R C and C9x say that&*
cancels out so that&*(vc1+200) == vc2+200
.89 C++, K&R C 9. 89 ,
&*(vc1+200)
vc1+200
( ) . C++ 89. K&R C 9 ,&*
, ..&*(vc1+200) == vc1+200
.
, &*(vc1+200)
*(vc1+200)
, .. ( ) &
.
NULL
,
const int NULL=0;
, , ( ) NULL
, 0
-- .
, NULL
static_cast<SomeType*>(0)
.
, , NULL
. , :
#include <stdio.h> #include <stdarg.h> #include <stdlib.h> void error(int stat ...) { va_list ap; va_start(ap, stat); while (const char* sarg=va_arg(ap, const char *)) printf("%s", sarg); va_end(ap); exit(stat); } int main() { error(1, " ", "", NULL); // , ! // NULL // static_cast<const char *>(0) }(, )
NULL
0L
( 0
) , sizeof(void*)==sizeof(long)>sizeof(int)
.
[2] :
bool
int
, char
int
, short
int;
B.6.1), float
double
.
struct A { private: void f(int); public: void f(...); }; void g() { A a; a.f(1); // : A::f(int), // g() }, : - .
va_start()
, va_end()
. , va_start()
, .
.
, . , , .
, va_end()
. , / C++ , .. "" std::cout
va_end()
.
cmp3
ssort()
, ssort()
mytype*
.
, . : , cmp3
ssort()
, cmp3()
mytype*
.
, ? ? - :
The reason for "discriminating against" floating points in constant expressions is that the precision of floating point traditionally varied radically between processors. In principle, constant expressions should be evaluated on the target processor if you are cross compiling."" , . , -, .
.. - , ( ) .
, - (, , ) , ..
class Curious { static const float c5=7.0; };() .
, . , :
#include <stdio.h> struct A { // int a; A(int a_) : a(a_) { printf("%d\n",a); } }; void f() { static int vals[]={2, 0, 0, 4}; static int curr=0; struct A_local : public A { // A_local() : A(vals[curr++]) { } }; A_local arr[4]; // A arr[4]; } int main() { f(); }.. , :
9.8 [class.local]
int x; void f() { static int s; int x; extern int g(); struct local { int g() { return x; } // , auto x int h() { return s; } // OK int k() { return ::x; } // OK int l() { return g(); } // OK }; // ... } local* p = 0; // : local
Y
X
X
, (scope), X
. .
complex r1=x+y+z; // r1=operator+(x,operator+(y,z))
:
complex r1=x+y+z; // r1=operator+(operator+(x,y),z):
(x+y)+z
.
// f() class X { friend void f(); // friend void h(const X&); // }; void g(const X& x) { f(); // f() h(x); // h() -- X }8- ,
f
, - f()
X
f
, f()
g()
.
String s1='a'; // : char String String s2(10); // : 10...
. .
X a=b;
a
X
X
. :
b
X
. :
X a(b);
b
X
. X
, :
X a(X(b));explicit-, .
12.8 [class.copy]
return
, ( cv-) , , . , , .
#include <stdio.h> #include <string.h> struct A { static const int nsize=10; char n[nsize]; A(char cn) { n[0]=cn; n[1]=0; printf("%5s.A::A()\n", n); } A(const A& a) { if (strlen(a.n)<=nsize-2) { n[0]='?'; strcpy(n+1, a.n); } else strcpy(n, ""); printf("%5s.A::A(const A& %s)\n", n, a.n); } ~A() { printf("%5s.A::~A()\n", n); } A& operator=(const A& a) { if (strlen(a.n)<=nsize-2) { n[0]='='; strcpy(n+1, a.n); } else strcpy(n, ""); printf("%5s.A::operator=(const A& %s)\n", n, a.n); return *this; } }; A f1(A a) { printf("A f1(A %s)\n", a.n); return a; } A f2() { printf("A f2()\n"); A b('b'); return b; } A f3() { printf("A f3()\n"); return A('c'); } int main() { { A a('a'); A b='b'; A c(A('c')); A d=A('d'); } printf("----------\n"); { A a('a'); A b=f1(a); printf("b %s\n", b.n); } printf("----------\n"); { A a=f2(); printf("a %s\n", a.n); } printf("----------\n"); { A a=f3(); printf("a %s\n", a.n); } },
main()
a
, b
, c
d
. :
a.A::A() b.A::A() c.A::A() d.A::A() d.A::~A() c.A::~A() b.A::~A() a.A::~A(), , , :
... c.A::A() ?c.A::A(const A& c) c.A::~A() d.A::A() d.A::~A() ?c.A::~A() .....
A c(A('c'))
A tmp('c'), c(tmp)
. , f1()
:
a.A::A() ?a.A::A(const A& a) A f1(A ?a) ??a.A::A(const A& ?a) ?a.A::~A() b ??a ??a.A::~A() a.A::~A()
a
?a
, f1()
. , f1()
?a
-- ??a
, . - : b ??a
, .. main()
b
-- , f1()
??a
, ( : , b ???a
).
-- , . f2()
f3()
:
A f2() b.A::A() ?b.A::A(const A& b) b.A::~A() a ?b ?b.A::~A() ---------- A f3() c.A::A() a c c.A::~A()
f3()
, f2()
-- ! , .
, .. ( !).
-- . :
#include <stdio.h> #include <string.h> struct A { static const int nsize=10; static int tmpcount; int val; char n[nsize]; A(int val_) : val(val_) // { sprintf(n, "_%d", ++tmpcount); printf("%5s.A::A(int %d)\n", n, val); } A(char cn, int val_) : val(val_) { n[0]=cn; n[1]=0; printf("%5s.A::A(char, int %d)\n", n, val); } A(const A& a) : val(a.val) { if (strlen(a.n)<=nsize-2) { n[0]='?'; strcpy(n+1, a.n); } else strcpy(n, ""); printf("%5s.A::A(const A& %s)\n", n, a.n); } ~A() { printf("%5s.A::~A()\n", n); } A& operator=(const A& a) { val=a.val; if (strlen(a.n)<=nsize-2) { n[0]='='; strcpy(n+1, a.n)