Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
GEK / ООП_ГОСЫ_ОТВЕТЫ.docx
Скачиваний:
68
Добавлен:
18.05.2015
Размер:
1.83 Mб
Скачать

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

Конструктором копирования (в англоязычной литературе используется термин copy constructor) называется специальный конструктор в языке программирования C++, применяемый для создания нового объекта как копии уже существующего. Такой конструктор принимает как минимум один аргумент: ссылку на копируемый объект.

Обычно компилятор автоматически создает конструктор копирования для каждого класса (известные как неявные конструкторы копирования, т.е. конструкторы копирования, заданные неявным образом), но в некоторых случаях программист создает конструктор копирования, называемый в таком случае явным конструктором копирования (или "конструктором копирования, заданным явным образом"). В подобных случаях компилятор не создает неявные конструкторы.

Конструктор C++ при копировании одного объекта в другой работает поэлементно. То есть в переменные экземпляра класса, в который производится копирование, копируются значения из соответствующих переменных экземпляра класса, который копируется. Чаще всего нам именно такое поведение и надо - но не всегда. Например, если у нас в классе есть указатель на экземпляр другого класса, то при таком способе копируется именно указатель, т. е. в двух копиях нашего класса указатель будет указывать на одну и ту же область памяти - что нам, скорей всего, не нужно. Для того, чтобы избежать это, мы долны написать для нашего класса конструктор копирования, в котором и определить способ копирования одного экземпляра нашего класса в другой.

Вот пример класса с конструктором копирования:

#include <iostream.h>

class B{

public:

int k;

B(){

k = 0;

}

};

class SomeClass{

public:

B *b;

SomeClass(){

b = new B;

}

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

SomeClass(const SomeClass & w){

this->b = new B;

this->b->k = w.b->k;

}

};

void main(){

SomeClass q;

SomeClass q1 = q; // Вызов конструтора копирования.

q1.b->k = 3;

cout << q.b->k;

}

Ситуация тут такая - в классе SomeClass есть указатель на класс B. В main мы создаем два экземпляра нашего класса SomeClass, и копируем один экземпяр в другой. Но при нашем копировании указатель на класс B не будет напрямую копироваться (т. е. адреса указателей на B у разных экземпляров класса SomeClass будут разные). И, как следствие, поменяв значение экземпляра класса B в одном экземляре класса SomeClass (в нашем случае q1) мы не поменяем значение экземпляра класса B в другом экземпляре класса SomeClass (в экземпляре q).

Таким образом наша программа выведет 0. А без определения конструктора копирования она бы вывела 3.

В C# не предусмотрен конструктор копии для объектов, однако его можно написать самостоятельно.

Пример

В следующем примере класс Personhttp://msdn.microsoft.com/ru-ru/library/0b0thckt.aspx определяет конструктор копии, который использует экземпляр Person в качестве аргумента. Значения свойств аргумента присвоенные свойствам нового экземпляра Person. Код содержит дополнительный конструктор копии, который отправляет свойства Name и Age экземпляра, который нужно скопировать конструктору экземпляра класса.

C#

class Person

{

// Copy constructor.

public Person(Person previousPerson)

{

Name = previousPerson.Name;

Age = previousPerson.Age;

}

//// Alternate copy constructor calls the instance constructor.

//public Person(Person previousPerson)

// : this(previousPerson.Name, previousPerson.Age)

//{

//}

// Instance constructor.

public Person(string name, int age)

{

Name = name;

Age = age;

}

public int Age { get; set; }

public string Name { get; set; }

public string Details()

{

return Name + " is " + Age.ToString();

}

}

class TestPerson

{

static void Main()

{

// Create a Person object by using the instance constructor.

Person person1 = new Person("George", 40);

// Create another Person object, copying person1.

Person person2 = new Person(person1);

// Change each person's age.

person1.Age = 39;

person2.Age = 41;

// Change person2's name.

person2.Name = "Charles";

// Show details to verify that the name and age fields are distinct.

Console.WriteLine(person1.Details());

Console.WriteLine(person2.Details());

// Keep the console window open in debug mode.

Console.WriteLine("Press any key to exit.");

Console.ReadKey();

}

}

// Output:

// George is 39

// Charles is 41

Соседние файлы в папке GEK