. C++ 3rd:  --------------------------------------------------------------- © Copyright , 2000 , 12 Oct 2004 Origin: http://ders.stml.net/cpp/ http://ders.stml.net/cpp/ ---------------------------------------------------------------

C++ 3rd:


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++. ? , C++. , . " C++", 3 . , C++ " C++", C++ -- , - C++ - . , , .

( ) 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 , -- !

, .


.43: 1.3.1.

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 -- " ".


.73: 2.5.5.

, 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);
 }
}
, .

.79: 2.7.2.

C++ , , , :
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 to vc1+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 dereference vc1+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) , .. ( ) &.


.128: 5.1.1.

, 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).

.192: 7.4.

...

[2] :

  1. , "" (" ") (, 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() 
}
, : - .

.199: 7.6.

, va_start(), va_end(). , va_start() , .

.

, . , , .

, va_end() . , / C++ , .. "" std::cout va_end() .


.202: 7.7.

, cmp3 ssort() , ssort() mytype*.

, . : , cmp3 ssort() , cmp3() mytype*.


.296: 10.4.6.2. -

, , .

, ? ? - :

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;
};
() .

.297: 10.4.7.

( ) .

, . , :

#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]

  1. ; (local) . (enclosing scope). , . , , extern , . :
    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   
  2. , (. 11 [class.access]). - , , .
  3. Y X X , (scope), X. .
  4. -.

.316: 11.3.1. - -

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.

.328: 11.5.1.

:
//  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() .

.333: 11.7.1.

String s1='a';  // :    char  String
String s2(10);  // :    10 
...

. .

X a=b;
a X X. :
  1. b X. :
    X a(b);
  2. b X . X, :
    X a(X(b));
    explicit-, .
, :

12.8 [class.copy]

  1. , , ( cv-), , , . 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)