Правила программирования на Си и Си++

       

Перегруженной бинарной операции


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

class string

{

   enum special_ { special };

   string( special_ ) {};              // ничего не делает.

   // ...

public:

   const string operator+( const

string r ) const;

   // ...

};

//------------------------------------------------------------

const string::operator+( const string r ) const



{

   string tmp( special );          // создать пустой объект

   tmp.buf = new char[ strlen(buf) + strlen(r.buf) + 1 ];

   strcpy( tmp.buf, buf );

   strcat( tmp.buf, r.buf );

   return tmp;

}

Многие компиляторы, получив вышеуказанное, генерируют довольно неэффективный код. Объект tmp

должен инициализироваться при вызове конструктора; здесь это не очень дорого, но обычно это ведет к значительно большим расходам. Конструктор копии должен быть вызван для выполнения оператора return, и сам объект также должен быть уничтожен.

Иногда вы можете улучшить такое поведение путем перегрузки встроенного псевдонима для операции приведения типа:

class string

{

   string(const char *left, const char *right );

public:

   const string string::operator+( const string r ) const

;

};

//-----------------------------------------------------------

string::string(const char *left, const char *right )

{

   buf = new char[ strlen(left) + strlen(right) + 1 ];

   strcpy( buf, left );

   strcat( buf, right );

}

//-----------------------------------------------------------

inline const

string::operator+( const string r ) const

{

   return string(buf, r.buf);

}

Более эффективные компиляторы здесь на самом деле рассматривают следующее:

string s1, s2;

s1 + s2;

как если бы вы сказали следующее (вы не можете сделать этого сами, потому что buf

является закрытым):

string(s1.buf, s2.buf)

Полезный результат заключается в устранении неявного вызова конструктора копии в операторе return в первом варианте реализации.



Содержание раздела