С++ для начинающих




Список инициализации членов - часть 5


// правильно: инициализируются константные члены и ссылки

ConstRef::

ConstRef( int ii )

        : ci( ii ), ri ( i )

{ i = ii; }

Каждый член должен встречаться в списке инициализации не более одного раза. Порядок инициализации определяется не порядком следования имен в списке, а порядком объявления членов. Если дано следующее объявление членов класса Account:

class Account {

public:

   // ...

private:

   unsigned int _acct_nmbr;

   double       _balance;

   string       _name;

};

то порядок инициализации для такой реализации конструктора по умолчанию

inline Account::

Account() : _name( string() ), _balance( 0.0 ), _acct_nmbr( 0 )

{}

будет следующим: _acct_nmbr, _balance, _name. Однако члены, указанные в списке (или в неявно инициализируемом члене-объекте класса), всегда инициализируются раньше, чем производится присваивание членам в теле конструктора. Например, в следующем конструкторе:

inline Account::

Account( const char* name, double bal )

       : _name( name ), _balance( bal )

{

       _acct_nmbr = get_unique_acct_nmbr();

}

порядок инициализации такой: _balance, _name, _acct_nmbr.

Расхождение между порядком инициализации и порядком следования членов в соответствующем списке может приводить к трудным для обнаружения ошибкам, когда один член класса используется для инициализации другого:

class X {

   int i;

   int j;

public:

   // видите проблему?

   X( int val )

      : j( val ), i( j )

      {}

   // ...

};

кажется, что перед использованием для инициализации i член j уже инициализирован значением val, но на самом деле i инициализируется первым, для чего применяется еще неинициализированный член j. Мы рекомендуем помещать инициализацию одного члена другим (если вы считаете это необходимым) в тело конструктора:

// предпочтительная идиома

X::X( int val ) : i( val ) { j = i; }

Упражнение 14.12

Что неверно в следующих определениях конструкторов? Как бы вы исправили обнаруженные ошибки?

(a) Word::Word( char *ps, int count = 1 )

         : _ps( new char[strlen(ps)+1] ),

           _count( count )

    {

         if ( ps )

            strcpy( _ps, ps );

         else {

            _ps = 0;

            _count = 0;

         }

    }

(b) class CL1 {

    public:

       CL1() { c.real(0.0); c.imag(0.0); s = "not set"; }

       // ...

    private:

       complex<double> c;

       string s;

    }

 (c) class CL2 {

    public:

       CL2( map<string,location> *pmap, string key )

            : _text( key ), _loc( (*pmap)[key] ) {}

       // ...

    private:

       location _loc;

       string   _text;

};




Содержание  Назад  Вперед