Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Книга C++.doc
Скачиваний:
24
Добавлен:
10.11.2019
Размер:
2.48 Mб
Скачать

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

имя_класса(const имя_класса & W){

тело конструктора

}

Здесь W является ссылкой на обьект в правой части инициализации. Конструктор копирования может иметь также дополнительные параметры, если для них определены значения по умолчанию.Однако в любом случае первым параметром должна быть ссылка на объект выполняющий инициализацию.

Памятка

Инициализация возникает в 3х случаях.

  1. Когда один объект инициализирует другой,

  2. когда объект передаётся в функцию по значению и

  3. когда объект служит в качестве возвращаемого значения функции.

Пример использования конструктора копирования.

Эта программа создает простой класс «Безопасный массив». Поскольку место для массива выделено с помощью new, то для выделения памяти в случае, когда один обьект используется для инициализации другого,предоставляется конструктор копирования

#include <iostream.h>

#include <stdlib.h>

// В классе array будет переменная указатель,переменная, отвечающая

// за размер массива,конструктор копирования и 2 функции одна

// для инициализации массива, другая для возврата i-го элемента

class array{

int *p;

int size;//размер массива

public:

array(int s){//конструктор

p=new int[s];//выделение памяти под массив

size=s;//Если все нормально то запоминаем размер массива

}

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

array(const array &d);

//инициализация массива

void Put(int i,int j){

if((i>=0)&&(i<size))// проверка на выход за границу массива

p[i]=j;

}

//получение i-го элемента

int Get(int i){

return p[i];

}

};

// тело конструктора копированяи

array::array(const array &f){

int i;

p=new int[f.size];//выделение памяти

if(!p)

exit(1);

for(i=0;i<f.size;i++)

p[i]=f.p[i]; //заполнение элементами из переданного массива

}

void main(){

array n(10);//создание обьекта класса array

int i;

for(i=0;i<10;i++)n.Put(i,i);//Заполнение исходного массива

for(i=9;i>=0;i--)cout<<n.Get(i);//Вывод на экран исходного массива

cout<<endl;

// создание нового обьекта и инициализация его уже существующим

// в этой строке происходит вызов конструктора копирования в качестве параметра

// ему передается n.

array x=n;

// Вывод на экран содержимого массива нового обьекта.

for(i=0;i<10;i++)cout<<x.Get(i);

}

Указатели на объекты

Темой нашего занятия будут опять указатели. Теперь это будут указатели на объекты. В С++ всё построено на указателях и с этим надо смириться. У меня для вас есть отличная новость: " Ваше знание указателей поможет вам в освоении нижеизложенного материала ". Итак стартуем !!! Как вы уже знаете в С++ для доступа к членам обьекта через сам обьект используется оператор " точка " ( . )

Пример

#include<iostream.h >

class Digit{

public:

int a;

};

void main(){

Digit z;

//доступ к переменной класса Digit через точку

z .a=3;

}

Здесь всё стандартно вы к этому уже должны были привыкнуть. Привыкли ? Тогда продолжаем !

Новая информация

Указатель может указывать не только на встроенный тип ( например на int или float ) , но и на тип определенный пользователем.Тип определенный пользователем - например структура , класс. В этом случае для доступа к членам через указатель необходимо использовать оператор стрелка ( -> ).Не ищите его на клавиатуре его там нет !Это комбинация - и > на клавиатуре.

Пример

// В этом примере показывается работа через оператор ->

// Есть класс Example в нем 1 переменная и 2 функции

#include<iostream.h >

class Example{

public:

int num;

//Функция для установки значения

void Set(int val){

num=val;

}

//Функция для показа значения

void Show();

};

void Example::Show(){

cout<<num;

}

void main(){

// Итак создаются обьект класса Example и указатель на этот класс

Example ex,*ptr;

// Непосредственная работа через обьект класса

ex.Set(1);

ex.Show();

// Присвоение адреса ptr адреса ex

ptr=&ex;

// Доступ с помощью Указателя

ptr->Show();

}

Важно

Здесь ключевой момент состоит в том что адрес объекта получен с использованием оператора взятия адреса & ,точно так же , как берется адрес переменной любого типа.

Итак запомните если вы работаете с обьектом класса необходимо использовать оператор " точка " ( . ) ,если же работа происходит через указатель на класс то " стрелка " ( -> ) единственно правильный выбор !!!

Инкремент ( ++ ) или декремент ( -- ) указателя изменяют его таким образом, что он всегда указывает на следующий элемент базового типа. Тоже самое и справедливо и для указателей на класс.

Пример

Итак предположим у нас стоит задача написать класс Точка и поработать с ним через указатель

#include<iostream.h>

class Point{

public:

// координаты точки

int x,y;

// функция для установки значений координат точки

void Set(int x1,int y1){

x=x1;

y=y1;

}

// функция для показа координат точки

void Show(){

cout<<"X is "<<x<<" Y is"<<y<<endl;

}

};

void main(){

// Создаем массив объектов класса Точка и указатель на этот класс

Point astr[2],*ptr;

// Задаем конкретные значения для элементов массива astr

astr[0].Set(2,3);

astr[1].Set(10,10);

// Присваиваем адрес первого элемента ( у него индекс 0 ) массива обьектов

//Point под названием astr указателю ptr ,имеющему также базовый тип

// Point.После этого можно с помощью ptr обращаться к элементам

// массива

ptr=astr;// После этого в ptr адрес элемента массива astr с индексом 0

ptr->Show();

// Каждый раз когда происходит инкремент адрес находящийся

// в ptr увеличивается на размер базового типа

ptr++;// После этого в ptr адрес элемента массива astr с индексом 1

ptr->Show();

ptr--;//После этого в ptr адрес элемента массива astr с индексом 0

ptr->Show();

}