Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ООП.doc
Скачиваний:
2
Добавлен:
14.07.2019
Размер:
399.36 Кб
Скачать

Void main()

{

MyClass a;

MyClass b=a;

}

В ДАННОМ примере происходит ошибка на этапе выполнения при вызове деструктора .

Так как при побитовом копировании из объекта a в объект b скопировался только адрес динамического массива . Следовательно оба объекта ссылаются на одну и туже динамическую память . При вызове деструктора b эта память удалится , а при вызове деструктора объекта а произойдет ошибка , так как в нем остался бит-указатель ссылающийся уже на удаленную память .

ПРИМЕР 2

Передача объекта в функцию в качестве параметров.

Void F(MyClass obj)

{

….

}

Void main()

{

MyClass a;

F(a);

}

Здесь при вызове функции Ф объекта а передается по значению , то есть будет производится копирование . Следовательно объект obj и объект а будут содержать адрес одной и той же динамической выделенной памяти .

При завершении работы функции Ф вызовется деструктор для obj и освободит динамическую память .

ПРИМЕР 3

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

MyClass F()

{

MyClass obj;

Return obj;

}

Void main()

{

F();

}

При возврате из функции в значение компилятор создает временный объект в который копируется возвращаемый объект .

В данном примере создастся временный объект , в который побитово скопируется obj .

При выходе из функции obj удаляется и вызывается деструктор . А во временном объекте остается указатель . При завершении работы функции мейн вызовется деструктор этого временного объекта , в котором произойдет ошибка при попытке освободить уже освобожденную память .

Для решения вышеописанных проблем используется конструктор копирования .

Синтаксис:

Имя_класса(имя_класса & obj)

Class MyClass

{

Int *p;

Public:

MyClass(const Myclass &obj)

{

P=new int[3];

For(int i=0;i<3;i++)

P[i]=obj.p[i];

}

};

Есть две формы вызова конструктора копирования!

1)MyClass a;

MyClas b=a;

2)MyClass c(a);

На самом деле конструктор копирования присутствует в классе всегда .

Если программист явно его не определяет , то компилятор его создает сам .

В этом случае копирование осуществляется побитово .

ПЕРЕГРУЗКА ОПЕРАЦИЙ ПРЕОБРАЗОВАНИЯ ТИПОВ

Синтаксис.

operator_тип_данных(для которого мы будем делать перегрузку)

{

тело

}

#include<iostream>

#include<stdio.h>

using namespace std;

class Drob

{

private:

int ch;

int zn;

public:

operator int()

{

return ch/zn;

}

operator double()

{

return (double)ch/zn;

}

};

Void main()

{

int n;

double d;

Drob obj(5,2);

n=(int)obj;

d=(double)obj;

n=obj;

d=obj;

}

Операторы преобразования типов можно перегружать только в виде методов класса.

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

Int n=3;

Drob a;

A=(Drob)n; //a=Drob(n);

КЛЮЧЕВОЕ СЛОВО EXPLICIT

Пример 1 .

void f(Drob a)

{

a.print();

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]