                            IV  

                                       13. 

591

    ,     ,  
   ,     .
,     ,  
    .

                                 13.1.  

        : ,   
class,     ,  ,    . 
         :

   class Screen { /* ... */ };
   class Screen { /* ... */ } myScreen, yourScreen;

        .    
      .       
    ,      .
        ,      :

      class,      .   
     obj1  First    ;
      .    obj2  Second  
    .

   class First obj1;
   Second obj2 = obj1; // : obj1  obj2   

         .     C 
     ;     C++ 
 .

                                     13.1.1. -

    -       
    .  ,   
,      :

   class First {
      int memi = 0; // 
      double memd = 0.0; // 
   };


                                  13.1.2. -

   -     :

   -      , ,   
        .  -    
            (.)   (->):

    myScreen.home();
    ptrScreen->home();

    (  13.9      );

   -      ,     
    ,       . , -
      ,  ,     - 
    .


                                    13.1.3.   

         . , 
    ,    -,  ,
            ;
       -   . , 
      ,   - ;
              
           . (  2  
          IntArray.  
       17,    .)

     ,     .
( ,     C++     
    - , .   [LIPPMAN96a].)   
    public, protected  private.  
     ,     .
    ,  ,   
 ,    private.


                                    13.1.4. 

         friend    
  .       ,   
,     .
         , -   
  .

                      13.1.5.    

     ,   . :

  class Screen; //   Screen

    ,        
.     ,      ,
          , 
   .
            ,   
  ,    . ,    
  ,    (*)   , 
          , 
    .

   class Screen; // 
   class StackScreen {
      int topStack;
      // :    Screen
      Screen *stack;
      void (*handler)();
   };

       ,     ,    
  -   .    ,
    ,     , 
     . :

   class LinkScreen {
      Screen window;
      LinkScreen *next;
      LinkScreen *prev;
   };


                              13.2.  

             . 
   ,    :

   class Screen {
      //  
   };

   int main()
   {
      Screen mainScreen;
   }


    Screen     ,    mainScreen  
   main().
        .    ,  ( 
      )   ( 
)  ,        
       .   
        . (   
     8.)
              . 
        .
:

   Screen bufScreen = myScreen;
   // bufScreen._height = myScreen._height;
   // bufScreen._width = myScreen._width;
   // bufScreen._cursor = myScreen._cursor;
   // bufScreen._screen = myScreen._screen;

   int main()
   {
      Screen myScreen, bufScreen[10];
      Screen *ptr = new Screen;
      myScreen = *ptr;
      delete ptr;
      ptr = bufScreen;
      Screen &ref = *ptr;
      Screen &ref2 = bufScreen[6];
   }

   #include "Screen.h"
   bool isEqual( Screen& s1, Screen *s2 )
   { //  false,    ,  true -  
      if (s1.height() != s2->height() || s2.width() != s2->width() )
         return false;

      for ( int ix = 0; ix < s1.height(); ++ix )
         for ( int jy = 0; jy < s2->width(); ++jy )
            if ( s1.get( ix, jy ) != s2->get( ix, jy ) )
               return false;

     return true; //  ? ,  
   }

           
   :   
(*)  ,    ,   
       . , 

   s2->height()

     :

   (*s2).height()

        .

                                   13.3. - 

            -, 
-    :

   Screen myScreen, groupScreen;
   myScreen.home();
   groupScreen.home();

      home()   myScreen     
_cursor.        groupScreen,   
  _cursor   ,    home()    . 
   -   -  ?  
  this,    .

                13.3.1.    -

    ,    home(), get(), height()  width()
    .    .
      -   ,    
,   . ,     
checkRange()      Screen.h,    
  .

   #include <iostream>

   #include "screen.h"

   //  -   Screen::
   bool Screen::checkRange( int row, int col )
   { //   
      if ( row < 1 || row > _height || col < 1 || col > _width ) {
         cerr << "Screen coordinates ( "
              << row << ", " << col
              << " ) out of bounds.\n";
         return false;
      }
      return true;
   }

    -,    ,   . 
    ,     inline 
          ,    
 .
      -       ,
  ,   ,     , 
     ,     . ,
   move()  get()    
 Screen.h    Screen.

                          13.3.2.    

     -       ,
      ,      ;
    -    ,    
      .

     copy()  :

   #include "Screen.h"

   int main()
   {
      Screen s1;
      //  s1
      Screen s2;
      s2.copy(s1);
      // ...
   }

  sobj   copy()    s1  
main(). - copy()    s2,   
.     _screen, _height, _width  _cursor,  
        ,    
s2.           
-   ,  , ,    
   this.

                      13.3.3.    -
 
   -       public, private  protected 
.     ?  -  ,
   .   -
  . , - home(), move()  get() 
Screen  ,      
 .
          ,  
 ,      Screen  
 -.       
       .
           . 
       , 
      .

       -  ,    
  ,       - (
) ,    ,     
  . 

                           13.3.4.  -

   , ,    Screen,     
   hi, wid  bkground:

   class Screen {
   public:
      Screen( int hi = 8, int wid = 40, char bkground = '#');
      //   -  
   };

      Screen  :

   Screen::Screen( int hi, int wid, char bk ) :
      _height( hi ), //  _height  hi
      _width( wid ), //  _width  wid
      _cursor ( 0 ), //  _cursor 
      _screen( hi * wid, bk ) //    hi * wid
                              //   
                              //  '#'
    {  //       
       //      14.5
    }

(  14 ,     
 .   15      .)


               13.3.5. -   const  volatile

           
  . :

     ,  ,    . 
      -.     
 ,     (,  
 )   (,    ) -:

      ,  -   ,
      const:

    ,   const,      -,
     const.   const 
     -.   -,
   ,       ,  
 :

       ,    -, 
 , .    const 
 -     . 
  ,  -    -, 
   ,       
 ,    .    
  . :

   #include <cstring>

   class Text {
   public:
      void bad( const string &parm ) const;
   private:
     char *_text;
   };

   void Text::bad( const string &parm ) const
   {
      _text = parm.c_str(); // :   _text
      for ( int ix = 0; ix < parm.size(); ++ix )
         _text[ix] = parm[ix]; //  ,   
   }

    _text ,     char*,  ,   
,     -  Text. -
 bad()    .  -
  ,        
,       .
    -       
 :

        const    ,   
  :

   int main() {
      const Screen cs;
      Screen s;

      char ch = cs.get(0,0); //   -
      ch = s.get(0,0); //   -
   }

          -, 
      .   
 ,    ,    , 
  .  ,    const
          
.
   -      volatile (   
 3.13).     volatile,    
,     (,   
,   /).     
-    ,   :

   class Screen {
   public:
      char poll() volatile;
      // ...
   };

   char Screen::poll() volatile { ... }

                     13.3.6.  mutable

       Screen    .
,     Screen,    
.         . 
    Screen:

   const Screen cs ( 5, 5 );

    ,    (3,4),   
:

   //      (3,4)
   // !   
   cs.move( 3, 4 );
   char ch = cs.get();

       : move()     -,  
  .  move()   :

   inline void Screen::move( int r, int c )
   {
      if ( checkRange( r, c ) )
      {
         int row = (r-1) * _width;
         _cursor = row + c - 1; //  _cursor
      }
   }

    ,  move()   _cursor, ,  
  .
       _cursor     Screen?
 _cursor    .  ,    
,       .  _cursor
     ,    Screen   const.
       ,   ,
   (mutable).      
,      .   ,  
 -   const.   
     mutable:

   class Screen {
   public:
      // -
   private:
      string _screen;
      mutable string::size_type _cursor; //  
      short _height;
      short _width;


         _cursor,  move() 
  .  move()   ,   
 .

   // move() -  -
   inline void Screen::move( int r, int c ) const
   {
      // ...
      // :  -   
      //   mutable
      _cursor = row + c - 1;
      // ...
   }

                               13.4.   this

          -.   
-     .
     move()    myScreen,   _width  _height, 
    ,     myScreen.   
   bufScreen,       
.    _cursor,   move(),  
 myScreen,  bufScreen?    this.
    -    ,    , 
this.
    this  ,    -,   
move()  myScreen     myScreen,     bufScreen 
  bufScreen.  ,  _cursor,    
move(),      myScreen,     bufScreen.
   ,   ,     this. 
    :

   1.   - ,   :

   // , ,   
   //  -
   //     C++
   inline void Screen::move( Screen *this, int r, int c )
   {
      if ( checkRange( r, c ) )
      {
         int row = (r-1) * this->_width;
         this->_cursor = row + c - 1;
      }
   }

        this     _width 
_cursor  .

   2.    -     
          ,    :

   myScreen.move( 2, 2 );

    

   move( &myScreen, 2, 2 );

         this  . , 
,   ,  - home()  :

   inline void Screen::home()
   {
      this->_cursor = 0;
   }

     ,      ,    
 - copy()  Screen.

                   13.4.1.    this

615

     main()  -  Screen   myScreen 
bufScreen  ,       .   
  - ,     
      . ,    main() 
 :


   int main() {
      // ...
      myScreen.clear().move( 2, 2 ), set( '*' ). display();
      // ? myScreen.clear().move( 2, 2 ). set( '*' ). display();
      bufScreen.reSize( 5, 5 ).display();

   ,   myScreen.clear(),  myScreen.move()  ..  
myScreen.move()     myScreen.clear(),  clear()  
  myScreen,     .   ,    
  -      this.   
clear():

   //  clear()    
   //       bkground = '#'
   Screen& Screen::clear( char bkground )
   {  //         
      _cursor = 0;
      _screen.assign( //   
         _screen.size(), // size() 
         bkground //   bkground
      );
      //  ,     
      return *this;
   }

    ,     -  Screen&   
   .   ,   
 move()  set().      void  Screen&,  
  *this.

    - display()   :

      reSize():

     this    ,    
-.   copy()   13.3      
:

   void Screen::copy( const Screen& sobj )
   {
      //    Screen  sobj -    ,
      //  
      if ( this != sobj )
      {
         //   sobj  this
      }
   }

    this   ,     -. 
,    sobj,    this,  sobj  this
      ,      . ( 
   ,     
   14.7.)

                                   13.7

    this      ,   
      . , - assign() 
classType  .    ,   ?

   classType& classType::assign( const classType &source )
   {
      if ( this != &source )
      {
         this->~classType();
         new (this) classType( source );
      }
      return *this;
   }

   ,  ~classType    .  new  
,         8.4.
      ?    ?
?

                        13.5.   

       ,        
 ,           
,      .   ,    
 .
            
:

            ,
     ,       
      ;
       ,     
      ,     .

          ,    .
           .   
      .   
 _interestRate:

   //     
   #include "account.h"

   double Account::_interestRate = 0.0589;

           .  , 
        ,  , 
   - .
          .    
, ,    .. :

   #include <string>

   class Account {
      // ...
   private:
      static const string name;
   };

   const string Account::name( "Savings Account" );

   ,      , 
,    .    
 ,        
. ,     nameSize 
 ,       -
   name.
          ,     
  .        ,
     .
     name    (   ),      .
       :

   class Account {
      //...
   private:
      static const int nameSize = 16; // :  
      static const string name[nameSize] = "Savings Account"; // 
   };

    name      .

    ,   nameSize    name  ,
   :

   const string Account::name[nameSize] = "Savings Account";

   nameSize     Account.     ,
 name    .    ? 
    - ,  
   .    name   
       ,    
  Account::name. (     
   13.9.)
       -      
 :
      ,    ,     
   . -,   :
       ,      , 
    :

   //        
   if ( Account::_interestRate < 0.05 )

        ,     
 ,      ,  
  .

            ,  
      .         
             
     - ,     :

   extern int var;

   class Foo {
   private:
      int var;
      static int stcvar;
   public:
      // :   Foo::var,
      //      
      int mem1( int = var );
      // :   static Foo::stcvar,
      //     
      int mem2( int = stcvar );
      // :     var
      int mem3( int = :: var );
   };


                               13.5.1.  -


     ,   -     
    .    
    _interestRate,   , 
   .
     -   ,   :  
     static,   const  volatile
.   ,    ,  static  
.
    -  this  ,    
        .  , 
         this ,
, . ,   -
dailyReturn()   ,    
  _amount.
    -     ,   
 .     ,   ,
      .

                           13.6.    

        op     
-  Screen.  repeat()    , 
  ,    switch  .  
        .

                           13.6.1.   

         -,   
      .
     ?  -    , 
 ,   ,  .   - 
       ,    : 
    ;   ;  ,
   .
      -          
,   this,         -. 
(    ,    .)    
      -      ,
  .
        Screen  short   :

   short Screen::*ps_Screen;

    ps_Screen    _height:

   short Screen::*ps_Screen = &Screen::_height;

    _width:

   short Screen::*ps_Screen = &Screen::_width;

     -      
,     . ,  ,  
    height()  width(),    
-  Screen  ,     int:

   int (Screen::*)()

     -  ,   :

   //    -     0
   int (Screen::*pmf1)() = 0;
   int (Screen::*pmf2)() = &Screen::height;
   pmf1 = pmf2;
   pmf2 = &Screen::width;

    typedef       .
,     -  Screen  , 
    Screen, ..

   Screen& (Screen::*)()

    typedef  Action   :

   typedef Screen& (Screen::*Action)();
   Action default = &Screen::home; 
   Action next = &Screen::forward;

      -     
     .      
     :

   Screen& action( Screen&, Action)();

   action()     :     Screen 
  - Screen  ,     
.  action()     :

   Screen meScreen;
   typedef Screen& (Screen::*Action)();
   Action default = &Screen::home;

   extern Screen& action( Screen&, Sction = &Screen::display );

   void ff()
   {
      action( myScreen );
      action( myScreen, default );
      action( myScreen, &Screen::end );
   }


                      13.6.2.      

              
     .       
 (.*         ->*  ). , 
 -    :

   int (Screen::*pmfi)() = &Screen::height;
   Screen& (Screen::*pmfS)( const Screen& ) = &Screen::copy;

   Screen myScreen, *bufScreen;

   //   -
   if ( myScreen.height() == bufScreen->height() )
      bufScreen->copy( myScreen );

   //    
   if ( (myScreen.*pmfi)() == (bufScreen->*pmfi)() )
      (bufScreen->*pmfS)( myScreen );

   

   (myScreen.*pmfi)()
   (bufScreen->*pmfi)();

 ,     () ,   
  -.  

   myScreen.*pmfi()

 

   myScreen.*(pmfi())

       pmfi()       
(.*). ,  pmfi    ,   
   .
     -  :

   typedef short Screen::*ps_Screen;
   Screen myScreen, *tmpScreen = new Screen( 10, 10 );

   ps_Screen pH = &Screen::_height;
   ps_Screen pW = &Screen::_width;

   tmpScreen->*pH = myScreen.*pH;
   tmpScreen->*pW = myScreen.*pW;

     - repeat(),      
.       -:

   typedef Screen& (Screen::Action)();

   Screen& Screen::repeat( Action op, int times )
   {
      for ( int i = 0; i < times; ++i )
         (this->*op)();
      return *this;
   }

           ,   repeat()
   :

   class Screen {
   public:
      Screen &repeat( Action = &Screen::forward, int = 1 );
      // ...
   };

      :

   Screen myScreen;
   myScreen.repeat(); // repeat( &Screen::forward, 1 );
   myScreen.repeat( &Screen::down, 20 );

     .    Menu     
-  Screen,    .
CursorMovements  ,      
Menu.

   Action::Menu() = {
      &Screen::home,
      &Screen::forward,
      &Screen::back,
      &Screen::up,
      &Screen::down,
      &Screen::end
   };

   enum CursorMovements { HOME, FORWARD, BACK, UP, DOWN, END };

      - move(),   
CursorMovements    Menu    -. 
 :

   Screen& Screen::move( CursorMovements cm )
   {
      ( this->*Menu[ cm ] )();
      return *this;
   }

       ([])  ,     
- (->*).    move()     
 Menu  -,       this
    -. move()    
,         
 .

                   13.6.3.     

            .
          
.        ,  .
      . (,   -
   this.)
            ,    
 ,    .     
 .   Account:

   class Account {
   public:
      static void raiseInterest( double incr );
      static double interest() { return _interestRate ; }
      double amount() { return _amount; }
   private:
      static double _interestRate;
      double _amount;
      string _owner;
   };

   inline void Account::raiseInterest( double incr )
   {
      _interestRate += incr;
   }


    &_interestRate   double*:

   //     &_interestRate
   double Account::*

      &_interestRate  :

   // : double*,   double Account::*
   double *pd = &Account::_interestRate;

       ,   ,     
:

   Account unit;
   //    
   double daily = *pd / 365 * unit._amount;

   ,  _interestRate  _amount   ,  
 - interest()   amount().
  interest()      :

   // 
   double (*)()

   -  Account:

   double (Account::*)()

        interest()   ,   
 :

   // : double(*pf)(),   double(Account::*pf)()
   double(*pf)() = &Account::interest;
   double daily = pf() / 365 * unit.amount();


                                  13.14

          - . 
  Screen ,       -
  ,  home()  end().

                        13.7.   ,  
634
       ,   :

          ,  . 
    ,  ,   
 . :

       -,   
:

   ,    ,   ,  
     ,    . ,  
    _ival,     ,
  _sval. ,   ,     .
        ,    ,
 ,   ,    
  .   Token      tok:

   char *idVal;
   //     ,    sval
   if ( curToken.tok == ID )
      idVal = curToken.val._sval;

      ,   ,    
      :

   #include <cassert>

   //      sval
   string Token::sval() {
      assert( tok==ID );
      return val._sval;
   }

        .     
       ,   .
,    Token  
,    :

   class Token {
   public:
      TokenKind tok;
      //    
      union {
         char _cval;
         int _ival;
         char *_sval;
         double _dval;
      } val;
   };

         ,    
 . , ,   Token,  
:

   class Token {
   public:
      TokenKind tok;
      //  
      union {
         char _cval;
         int _ival;
         char *_sval;
         double _dval;
      };
   };

    -        
,    .
         ,   
       Token.       
 ,   -.  ,  
  ,      
    static.
     lex(),   :

   int lex() {
      Token curToken;
      char *curString;
      int curIval;

      // ... ,    
      // ...   curToken
      case ID:
         curToken.tok = ID;
         curToken._sval = curString;
         break;
      case Constant: //  
         curToken.tok = Constant;
         curToken._ival = curIval;
         break;
      // ...  ..
   }


                     13.8.    ,  

639
             ,
  .      ,    
:

   class File {
      // ...
      unsigned int modified : 1; //  
   };

        ,    
,   .  , modified      .
 ,     ,    
    ,     . , 
          
unsigned int,     mode:

   typedef unsigned int Bit;

   class File {
   public:
      Bit mode: 2;
      Bit modified: 1;
      Bit prot_owner: 3;
      Bit prot_group: 3;
      Bit prot_world: 3;
      // ...
   };

         ,     .
           1 ( 
     4.11):

   enum { READ = 01, WRITE = 02 }; //   

   int main() {

       File myFile;
       myFile.mode |= READ;
       if ( myFile.mode & READ )
          cout << "myFile.mode is set to READ\n";

   }

           (&),     
   -.  ,    
.
      C++    bitset,  
   .     
 . (  bitset      
  4.12.)


                    13.9.    A

   (  17  18  ,      
  .)

           
  .         
 ,         .
          :    , 
  . ,    operator[]() 
  typedef index_type,    
operator[]()  ,      

   class String {
   public:
      // :  index_type  
      char &operator[]( index_type );
      typedef int index_type;
   };


         .   ,  
  -,   ,   
 .   .
        -    .
   (..      )
   ,      .  
     ,   ,  
   .    ,   

   class String {
   public:
      typedef int index_type;
      char &operator[]( index_type elem )
      { return _string[ elem ]; }
   private:
      char *_string;
   };

       ,    operator[](),
     index_type.     ,
      -,   index_type 
    operator[]().
    ,   _string      
operator[]().  ,  _string     operator[]()
 .    -   
      -.  
     ,     -
 ,     ,    
 .
          . ,  
- clear()     bkground, 
 :

   class Screen {
   public:
      // bkground    ,
      //     
      Screen& clear( char = bkground );
   private:
      static const char bkground = '#';
   };

        -    
 ,    ,    
 .         
     ,    .  
        .  
  :

   class Screen {
   public:
      // ...
      // : bkground -  
      Screen& clear( char = bkground );
   private:
      const char bkground = '#';
   };

        bkground,  
 .
     ,    ,      
,      .    
   ,       
      .
     -     . 
  ,        
,      .

    _interestRate   -
Account::initInterest()   ,      
.
     ,   ,      
_interestRate     ,     
Account.      name    
  nameSize:

   class Account:
     // ...
   private:
      static const int nameSize = 16;
      static const char name[nameSize];
      // nameSize     Account
   };

   const char Account::name[nameSize] = "Savins Account";

     ,    ,    
      .       
     . ,  
   typedef Money,    Account,  
Money   ,      
 :

   class Account {
      typedef double Money;
      //...
   private:
     static Money _interestRate;
     static Money initInterest();
   };

   // Money      Account::
   Account::Money Account::_interestRate = initInterest();

         ,   
   .        
   ,         
. (       17  18.)


               13.9.1.      

   , ,     ,    
 .         ,  
  .

   ,     (  
 -    ),  
:

   ,    - ,  
:

   ,     -,  :

  ,      ,  
:

                             13.10.   A

        .

   class List {
   public:
      // ...
   private:
      //  
      class ListItem;
      ListItem *list;
      ListItem *at_end;
   };
 
   //       
   class List::ListItem {
   public:
      ListItem( int val=0 );
      ListItem *next;
      int value;
   };

        ListItem   
   List.

        13.10.1.       


                    13.11.      A

            
 .        
.  ,   ,    
  , ..     ,  
  .

         ,   (-, 
   )      .   
        
 ,     ,    
?       ,   
  ,       .  
     :

   // --- primer.h ---

   namespace cplusplus_primer {
      class List {
         // ...
      private:
         class ListItem {
         public:
            void check_status();
            int action();
            // ...
         };
      };
   }

   // --- primer.C ---
   #include "primer.h"

   namespace cplusplus_primer {
      // : check_status()      ,
      //   List
     void List::ListItem::check_status() { }
   }

   // : action()     
   //   ,    List
   //     
   int cplusplus_primer::List::ListItem::action() { }


                                 13.12.   A

   ,    ,  .    
  ,  .   , 
    ,    ,   
,   .  -  
     .    
    ;   ,   
 .
