/* конструктором копирования по */
/* умолчанию конструкторов */
/* копирования членов */
#include
#include
#include
#include
using namespace std ;
const int MAXNAMESIZE = 40 ;
class Student
{
public :
Student( char *pName = "no name" )
{
strcpy( name , pName ) ;
cout << "Конструируем " << name << endl ;
}
Student( Student & s )
{
strcpy( name , "Копия " ) ;
strcat( name , s.name ) ;
cout << "Сконструирована " << name << endl ;
}
~Student( )
{
cout << "Деструкция " << name << endl ;
}
protected :
char name[ MAXNAMESIZE ] ;
} ;
class Tutor
{
public :
/* Вызов конструктора копирования Student */
Tutor( Student & s ) : student( s )
{
cout << "Конструирование объекта Tutor" << endl ;
id = 0 ;
}
protected :
_________________
216 стр. Часть 3. Введение в классы
Student student ;
int id ;
} ;
void fn( Tutor tutor )
{
cout << "В функции fn( )" << endl ;
}
int main( int argcs , char* pArgs[ ] )
{
setlocale ( LC_ALL , ".1251" ) ; /* печать кириллицы */
Student Chester( "Chester" ) ;
Tutor tutor( Chester ) ;
cout << "Вызов fn ( )" << endl ;
fn( tutor ) ;
cout << "Возврат из fn( )" << endl ;
/* Пауза для того, чтобы посмотреть на результат работы программы */
system( "PAUSE" ) ; return 0 ;
}
Запуск этой программы приведёт к выводу таких сообщений:

Конструируем Chester
Сконструирована Копия Chester
Конструирование объекта Tutor
Вызов fn( )
Сконструирована Копия Копия Chester
В функции fn( )
Деструкция Копия Копия Chester
Возврат из fn( )
Press any key to continue . . .
Деструкция Копия Chester
Деструкция Chester
Конструирование объекта Chester приводит к вызову конструктора Student , который выводит первое сообщение. Конструктор объекта tutor вызывает копирующий конструктор Student для генерации собственного члена student , и приводит к выводу следующих двух строк.
Затем программа передаёт копию объекта Tutor в функцию fn( ) . Поскольку класс Tutor не определяет копирующий конструктор, программа вызывает конструктор копирования по умолчанию.
Конструктор копирования по умолчанию Tutor вызывает конструкторы копирования для членов-данных. Копирующий конструктор для int просто копирует значение, но конструктор копирования Student генерирует вывод на экран строки Сконструирована Копия Копия Chester . Деструктор копии вызывается как часть возврата из функции fn( ) .
►"Мелкие " и "глубокие " копии...217
Выполнение поэлементного копирования — естественная задача конструктора копирования. Но что ещё можно сделать с помощью такого конструктора? Когда наконец можно будет попытаться сделать что-то поинтереснее, чем программирование поэлементного копирования и объединения каких-то строк с именем несуществующего студента?
_________________
217 стр. Глава 18. Копирующий конструктор
Представим ситуацию, когда конструктор распределяет для объекта некоторые системные ресурсы, например память из кучи. Если копирующий конструктор будет выполнять простое копирование без выделения памяти из кучи для копируемого объекта, может возникнуть ситуация, когда два объекта будут считать, что именно они являются владельцами одного блока памяти. Ситуация ещё более усугубится при вызове деструкторов обоих объектов, которые попытаются освободить одну и ту же память. Взгляните на приведённый ниже пример.
/* ShallowCopy — мелкое копирование */
/* неприменимо при захвате */
/* ресурсов */
//
#include
#include
#include
#include
using namespace std ;
class Person
{
public :
Person( char *pN )
{
cout << "Конструирование \" " << pN << " \" " << endl ;
pName = new char[ strlen( pN ) + 1 ] ;
if ( pName != 0 )
{
strcpy( pName , pN ) ;
}
}
~Person( )
{
cout << "Деструкция \" " << pName << " \" " << endl ;
strcpy( pName , "Уже освобождённая память" ) ;
/* delete pName ; */
}
protected :
char *pName ;
} ;
void fn( )
{
/* Создание нового объекта */
Person p1( "Достаточно длинное имя" ) ;
/* Копирование p1 в р2 */
Person p2(p1);
Читать дальше