►Автоматический конструктор копирования 215
►"Мелкие" и "глубокие" копии 217
►Временные объекты 221
Конструктор — это специальная функция, которая автоматически вызывается С++ при создании объекта с тем, чтобы предоставить ему возможность проинициализировать самого себя. В главе 16, "Создание и удаление объектов", описаны основные концепции применения конструкторов, в главе 17, "Аргументация конструирования", вы познакомились с разными типами конструкторов. А в настоящей главе рассматривается частный случай, известный под названием копирующего конструктора ( или конструктора копирования ).
►Копирование объекта...213
Конструктор, который используется С++ для создания копий объекта, называется копирующим конструктором, или конструктором копирования. Он имеет вид X::Х( Х& ) ( или X::X( const Х& ) ), где X — имя класса. Да, это не ошибка — это действительно конструктор класса X, который требует в качестве аргумента ссылку на объект класса X. Это звучит несколько бессмысленно, но не торопитесь с выводами и позвольте объяснить, зачем такое "чудо" в С++.
Зачем нужен копирующий конструктор...213
Подумайте о том, что будет происходить в программе, если вы вызовете следующую функцию:
void fn( Student fs )
{
/* Некоторые действия */
}
int main( int argcs , char* pArgs[ ] )
{
Student ms ;
fn( ms ) ;
return 0 ;
}
При вызове описанной функции fn( ) ей будет передан в качестве аргумента не сам объект, а его копия.
_________________
213 стр. Глава 18. Копирующий конструктор
«В С++ аргументы функции передаются по значению.»
[Помни!]
Теперь попробуем понять, что же значит — создать копию объекта. Для этого требуется конструктор, который будет создавать объект ( даже если копируется уже существующий объект ). С++ мог бы побайтово скопировать существующий объект в новый, но как быть, если побайтовая копия не совсем то, что нам нужно? Что, если мы хотим нечто иное? ( Не спрашивайте у меня пока, что такое это "иное" и зачем оно нужно. Немного терпения! ) У нас должна быть возможность самим определять, как будет создаваться копия объекта.
Таким образом, в приведённом выше примере необходим копирующий конструктор, который будет выполнять копирование объекта ms при вызове функции fn( ). Этот частный копирующий конструктор и есть Student::Student( students ) ( попробуйте-ка произнести эту скороговорку... ).
Использование конструктора копирования ...214
Лучший путь понять, как работает конструктор копирования, — это увидеть его в действии. Рассмотрим приведённый ниже пример с классом Student.
//
/* CopyConstructor — работа конструктора копирования */
//
#include
#include
#include
#include
using namespace std ;
const int MAXNAMESIZE = 40 ;
class Student
{
public :
/* conventional constructor — обычный конструктор */
Student( char *pName = "no name" , int ssId = 0 )
{
strcpy( name , pName ) ;
id = ssId ;
cout << "Конструируем " << name << endl ;
}
/* Копирующий конструктор */
Student( Student& s )
{
strcpy( name , "Копия " ) ;
strcat( name , s.name ) ;
id = s.id ;
cout << "Сконструирована " << name << endl ;
}
~Student( )
{
cout << "Деструкция " << name << endl ;
}
protected :
_________________
214 стр. Часть 3. Введение в классы
char name[ MAXNAMESIZE ] ;
int id ;
} ;
/* fn — передача параметра по значению */
void fn( Student copy )
{
cout << "В функции fn( )" << endl ;
}
int main( int nNumberofArgs , char* pszArgs[ ] )
{
setlocale ( LC_ALL , ".1251" ) ; /* печать кириллицы */
Student Chester( "Chester" , 1234 ) ;
cout << "Вызов fn( )" << endl ;
fn( Chester ) ;
cout << "Возврат из fn( )" << endl ;