Читайте также: |
|
Конструкторы и деструкторы. Список инициализации элементов. Конструкторы по умолчанию и конструкторы копирования. Использование конструкторов для инициализации переменных-членов класса. Использование конструкторов и деструкторов для выделения и освобождения
Конструктор и деструктор являются методом класса. Отсутствие их описания не значит, что их не применили.
Начнем с того, что когда мы создаем элементы (переменные) класса, мы не можем присвоить им значения в самом определении класса. Компилятор выдаст ошибку. Поэтому нам необходимо создавать отдельный метод (так называемую set-функцию) класса, с помощью которого и будет происходить инициализация элементов. При этом, если необходимо создать, к примеру, 20 объектов класса, то чтобы инициализировать элементы потребуется 20 раз вызвать set-функции.
Тут нам как раз сможет помочь конструктор класса. Конструктор – это метод класса, где имя класса совпадает с именем этого метода и который предназначен для инициализации элементов класса некоторыми начальными значениями, т.е. выполняется всегда в момент создания объекта.
Деструктор (от слова destruct — разрушать) — специальный метод класса, который служит для уничтожения элементов класса. Чаще всего его используют тогда, когда в конструкторе,при создании объекта класса, динамически был выделен участок памяти и необходимо эту память очистить, если эти значения уже не нужны для дальнейшей работы программы.
Правила, используемые для Конструктора (К):
1. Для К не указывается тип возвращаемого значения;
2. К не может возвращать значения
3. К не наследуется
4. К не может быть объявлен с помощью модификатора const, static, virtual, volatile.
Правило для Деструктора (Д):
1. Д не может иметь параметр;
2. имя деструктора идентично имени конструктора, но с приставкой ~
3. Д не возвращает значения;
4. Д не наследуется;
5. Класс имеет один деструктора;
6. Не используется модификаторами const, volatile, static.
Class AnyClass
{
Int a,b;
public:
AnyClass (int x, int y) “// К с параметрами//
~AnyClass(); //деструктор…
void Show();
};
AnyClass::AnyClass (int x, int y)
{
cout<<”Мы в конструкторе\n”;
a=x;
b=y;
}
AnyClass:: ~AnyClass()
{
cout<<”Мы в деструкторе\n”;
getchar();getchar();
}
void AnyClass::Show()
{
cout<<a<<’ ‘<<b<<”\n”;
}
int main()
{
Setlocale(LC_ALL, “Rus”);
AnyClass ob(3,7);
Ob. Show()
…
return 0;
}
Классический вариант инициализации данных в теле конструктора можно выполнить с помощью списка инициализации элементов. Следующий пример показывает два сходных класса с конструкторами, применяющими два метода инициализации. Первый использует список инициализации, а второй присваивает элементам значения в теле конструктора.
Например:
class CXYValue
{
int iX, iY;
public:
CXYValue(int _iX, int _iY): iX(_iX), iY(_iY){};
};
class CXYValue
{
int iX, iY;
public:
CXYValue(int _iX, int _iY)
{ iX = _iX; iY = _iY; };
};
Список отделяется: от определения функции и содержит данные-члены и базовые классы.
Для каждого элемента в () и за ними может указываться 1 или больше параметров, используемых при инициализации.
Список является единственным методом определения констант и ссылок.
Конструктор по умолчанию — это довольно простая конструкция, которая сводится к созданию для типа конструктора без параметров.
Если в классе не объявляются конструкторы, компилятор предоставляет конструктор по умолчанию:
class DefaultСonstructor {
int a = 10;
public int getInt() {
return a;
}
}
class Main {
public static void main(String[] args) {
DefaultСonstructor Dc = new DefaultСonstructor();//Конструктор по умолчанию
System.out.println(Dc.getInt());
}
}
Конструктор копирования создает объект класса, копируя при этом данные из уже существуещего объекта данного класса, поэтому конструктор имеет единственный параметр – ссылку на объект класса. Ссылка может записываться: X(const X&); X(X&);Существует 2 разновидности копирования данных:
1. Поверхностное (передача только адреса от одной к другой переменной. Оба объекта ссылаются на одну и ту же ячейку данных);
2. Глубинное (происходит копирование из одной области в другую);
Для классов, создаваемых указатели и ссылки следует включать в определении класса, конструктор копирования которого выполняет глубинное копирование.
Конструктор, создаваемый компилятором выполняет поверхностное копирование.
Полный конструктор позволяет явно инициализировать все переменные-члены класса.
// описание полного конструктора
Lens(double r1,double r2,double D, double d, double n);
// реализация полного конструктора
Lens::Lens(double r1, double r2, double D, double d, double n)
{
m_R1=r1;
m_R2=r2;
m_d=d;
m_D=D;
m_n=n;
}
Если при описании экземпляра класса в скобках указать параметры, при создании экземпляра класса будет вызван полный конструктор и переменные-члены инициализируются указанными значениями.
// вызов полного конструктора
Lens test_lens(10., -10., 2., 5., 1.5);
Неполный конструктор
Возможен и неполный конструктор, когда в списке параметров указываются не все возможные параметры для инициализации членов класса, а только наиболее часто используемые. Остальные параметры будут инициализированы значениями по умолчанию.
// описание неполного конструктора
Lens(double r1, double r2);
// реализация неполного конструктора
Lens::Lens(double r1, double r2)
{
m_R1=r1;
m_R2=r2;
m_d=0.;
m_D=0.;
m_n=1.;
}
// вызов неполного конструктора
Lens lens(10., -10.);
Инициализация переменных-членов класса в конструкторах может осуществляться не только в теле конструктора, но и после оператора:. При этом, во время присваивания переменной-члену значения, будет вызываться не оператор присваивания, а конструктор. Для встроенных типов данных, таких как double или int, это не существенно, но если членами класса являются абстрактные типы, вызов конструктора вместо оператора присваивания будет выполняться быстрее.
Lens::Lens(double r1, double r2)
: m_R1(R1)
, m_R2(R2)
{
m_d=2.;
m_D=5.;
m_n=1.5;
}
или такой вариант:
Lens::Lens(double R1, double R2)
: m_R1(R1)
, m_R2(R2)
, m_d(2.)
, m_D(5.)
, m_n(1.5)
{
}
Деструктор - осуществляет освобождение памяти, уничтожение объектов размещенных динамически
Matrix::Matrix(int r, int c)
{
m_data=new float[r*c];
}
Matrix::~Matrix()
{
delete []m_data;
}
В ООП выделение выполняется с помощью перезагружаемой операции new. Для освобождения – delete.
Дата добавления: 2015-09-03; просмотров: 136 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Подсистема ДП | | | Перезагрузка конструкторов |