Утечка памяти и методы ее устранения.




Код программы и все, что могут по нему спросить

 

#include<iostream.h>

#include "string.h"

class A{ // cуперкласс

public:

A(){a=0; cout<< "A a="<<a<<endl;};

~A(){cout << "~A"<<endl;};

virtual int Ma() // virtual для замещения функции

{return a;}

protected:

int a;

};

class B:public A{ // подкласс

public:

B(){a=1; cout<< "B a="<<a<<endl;}

~B(){cout << "~B"<<endl;};

virtual int Ma() //замещение функции

{return a;}

};

class C:public B{ // подкласс

public:

C(){a=2;cout<< "C a="<<a<<endl;}

~C(){cout << "~C"<<endl;};

virtual int Ma() //замещение функции

{return a;}

};

int main() {

A *a; // а - полиморфная переменная, т.е. указатель на абстрактный базовый тип... В нашем случае, мы говорим что а - указатель на объект класса А

a = new A; // - создание динамического объекта

cout<<a->Ma()<<endl;

cout<<" создать объект B " <<endl;

a = new B; // Выполняется принцип подстановки. Функция new выделяет память, размера B, под объект класса B, и возвращает нам адрес ячейки памяти, где она выделилась... т.е. мы присваиваем указателю а адрес ячейки, и теперь а - это указатель на ячейку памяти, в которой хранится объект B...

cout<<a->Ma()<<endl; //(Мы через указатель общаемся с классом В и вызываем функцию Ма()) полиморфный вызов – тут происходит замещение т е используется функция Ма не та, что описана в суперклассе А, а та, что описана в подклассе В

 

Более подробное разъяснение:

Мы заходим в ячейку памяти, на которую указывает а и берем там объект, который там лежит, и на нем выполняем функцию Ма(), в данном случае мы заходим в ячейку, на которую указывает а, и в которой лежит объект b, затем через объект выполняем функцию.

Функция Ма() описана в суперклассе (в остальных она лишь переопределена), поэтому при ее вызове мы сначала обращаемся в суперкласс, где есть виртуальная функция. Мы смотрим, на что указывает указатель а? в нашем случае он указывает на ячейку с объектом В, значит мы переходим в класс В и там выполняем эту функцию; то есть происходит замещение функции (полиморфный вызов).

Замещение - это возможность функции по-разному реагировать на обращение к ней, т.е. при обращении к ней она будет по-разному выполнятся, в зависимости, на что указывает указатель а.

 

cout<<" создать объект C " <<endl;

a = new C; // выполнение принципа подстановки

cout<<a->Ma()<<endl;

// C* c = dynamic_cast <C*> (a); // проверяет на соответствие полиморфную переменную и указанный в этой строке тип.

// if(c!= NULL)

// {cout<<"a pointer C"<<endl; }

cout<<" вызов диструктора объекта с " <<endl;

{

C c;

} // вызов диструктора объекта с

cout<< "выход из программы"<<endl;

return 0;

}

Принцип подстановки (формулировка).

Принцип подстановки – это принцип, позволяющий вместо объектов (а) суперкласса (А), подставить объекты (в,с…) подклассов (В,С…) не зависимо от уровня иерархии и без видимых изменений поведения.

Этот принцип выполняется в строках a = newB; и a = newC; т.к. здесь вместо объектов суперкласса А, подставляются объекты классов B и С.

 

Последовательность создания и разрушения объектов.

Объекты создаются последовательно таким образом, что первым создается всегда объект суперкласса, а затем уже объекты наследуемых классов. Например:

При создании объекта типа В у нас сначала идет обращение к конструктору объекта из суперкласса А, а уже затем программа обращается к конструктору объекта подкласса В.

Соответственно, при создании объекта класса С, происходит все тоже самое в том же порядке, только после конструирования объекта класса В еще конструируется объект класса С.


Удаление объектов: допустим a=newC;
чтобы удалить при виртуальном деструкторе, нужно написать
delete a; тогда у нас выполнится ~C() ~B() ~A()
если мы напишем delete a; при не виртуальном деструкторе, то у нас удалится только объект a. Чтобы удалить при не виртуальном деструкторе, нужно написать delete (C*) a; - это динамическая типизация, т.е. мы сначала приводим а к типу с и сразу удаляем с, а не последовательно...Т.е. при не виртуальном деструкторе надо писать delete (C*) a; и тогда всё удалится корректно

 

Замещение.

Замещение - это возможность функции по-разному реагировать на обращение к ней, т.е. при обращении к ней она будет по-разному выполнятся, в зависимости, на что указывает указатель а.

(Замещаемая функция способна обеспечить полиморфное поведение в соответствии с типом, который переменная имеет при вызове функции.)

Виртуальная функция - функция класса, которая может быть переопределена в классах-наследниках так, что конкретная реализация метода будет определяться во время исполнения.

 

Полиморфизм

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

 

Утечка памяти и методы ее устранения.

Утечка памяти- неконтролируемый процесс уменьшения объема оперативной памяти компьютера, связанный с ошибками в работающих программах, вовремя не освобождающих ненужные участки памяти или с ошибками системных служб контроля памяти

Методы устранения:

· Отказ от использования динамических переменных

· «Сборка мусора»(своевременное очищение ненужных участков памяти)

 



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2016-04-26 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: