Конструкторы копирования. Пример
Он используется для копирования объекта в заново создаваемый объект. Он используется в процессе инициализации, а не во время обычного присваивания.
Его прототип всегда следующий:
Имя_класса(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;
}
- поскольку была создана строка в heap-памяти, операторы new[], то и удалять надо оператором delete[].
- из static метода невозможно получить доступ к переменным объектам.
- для обращения к static – методу или к static переменной из public раздела декларации надо обращаться через префикс «Класс::», напр..: int count = String::HowMany();
- применение конструктора копирования в этом примере чрезвычайно важно. Без него возникает опасность «висячих ссылок».
Рассмотрим более подробно:
Без конструктора копирования при инициализации другого объекта возникает ситуация
Пусть исходный объект удалялся, например, выходом из блока или как-то ещё. Тогда возникает ситуация, что строка символов удалена и возникает висячая ссылка:
Теперь, если конструктор копирования декларирован так, как он представлен выше, то исходный объект и 2-й объект ссылаются на свой экземпляр строки.
Дата добавления: 2016-05-26; просмотров: 1911;