Конструкторы копирования. Пример


Он используется для копирования объекта в заново создаваемый объект. Он используется в процессе инициализации, а не во время обычного присваивания.

Его прототип всегда следующий:

Имя_класса(const Имя_класса&)

Если конструктор копирование не определён, то он автоматически определяется компилятором и реализует поэлементное копирование, что не всегда верно по условиям работы программы.

Пример:

Пусть уже имеется объект класса String - motto (переменная). Тогда в следующих случаях вызывается конструктор копирования:

 

String ditto(motto);

String metoo = motto;

String also = String(motto);

String *pString = new String(motto);

 

В последнем случае создаётся новый объект и для его инициализации используется конструктор копирования и затем присвоение указателя на этот объект переменной pString;

Ясно что в правило применения конструктора копирования входят и ситуации когда передаются аргументы в функцию – объекты класса или возвращаются оператором return значения – объекты классов. Ведь в этих случаях создаются копии исходных объектов и они инициализируются конструктором копирования.

Напомню, что если он явно не декларирован, то компилятор декларирует его неявно в виде прямого копирования полей исходного объекта.

 

Пример.

 

class String

{

private:

char* str;//указатель на строку

int len;//длина строки

static int num_strings;//кол-во объектов класса String;

public:

static int HowMany(){return num_strings;}

String(const char* s);//конструкторы

String();

String(const String& st);//конструктор копирования

~String();//деструктор

 

};

 

В декларации объекта переменная static класса памяти, она определяет свойство всего класса объектов. В реализации класса должна быть stratic – переменной так:

int String::num_strings = 0;

Реализация конструкторов и деструкторов.

String::String(const char* s)

{

len = strlen(s);

str = new char[len+1];

strcpy(str,s);

num_strings++;

}

String::String()

{

len = 4;

str = new char[len+1];

strcpy(str,"C++");

num_strings++;

}

String::String(const String& st)

{

len = strlen(st.s);

str = new char[len+1];

strcpy(str,st.s);

num_strings++;

}

 

String::~String()

{

--num_strings;

delete[] str;

}

 

  1. поскольку была создана строка в heap-памяти, операторы new[], то и удалять надо оператором delete[].
  2. из static метода невозможно получить доступ к переменным объектам.
  3. для обращения к static – методу или к static переменной из public раздела декларации надо обращаться через префикс «Класс::», напр..: int count = String::HowMany();
  4. применение конструктора копирования в этом примере чрезвычайно важно. Без него возникает опасность «висячих ссылок».

 

Рассмотрим более подробно:

Без конструктора копирования при инициализации другого объекта возникает ситуация

Пусть исходный объект удалялся, например, выходом из блока или как-то ещё. Тогда возникает ситуация, что строка символов удалена и возникает висячая ссылка:

Теперь, если конструктор копирования декларирован так, как он представлен выше, то исходный объект и 2-й объект ссылаются на свой экземпляр строки.

 



Дата добавления: 2016-05-26; просмотров: 1889;


Поиск по сайту:

Воспользовавшись поиском можно найти нужную информацию на сайте.

Поделитесь с друзьями:

Считаете данную информацию полезной, тогда расскажите друзьям в соц. сетях.
Poznayka.org - Познайка.Орг - 2016-2024 год. Материал предоставляется для ознакомительных и учебных целей.
Генерация страницы за: 0.008 сек.