Главная

Популярная публикация

Научная публикация

Случайная публикация

Обратная связь

ТОР 5 статей:

Методические подходы к анализу финансового состояния предприятия

Проблема периодизации русской литературы ХХ века. Краткая характеристика второй половины ХХ века

Ценовые и неценовые факторы

Характеристика шлифовальных кругов и ее маркировка

Служебные части речи. Предлог. Союз. Частицы

КАТЕГОРИИ:






Конструкторы копирования




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

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

Имя_класса(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-й объект ссылаются на свой экземпляр строки.

 






Не нашли, что искали? Воспользуйтесь поиском:

vikidalka.ru - 2015-2024 год. Все права принадлежат их авторам! Нарушение авторских прав | Нарушение персональных данных