Конструкторы и деструкторы
В С++ определены два специальных типа методов – конструкторы и деструкторы. Конструкторы предназначены для инициализации элементов данных объектов. Деструкторы – для их удаления.
Описание конструктора:
идентификатор_конструктора (список параметров) {тело конструктора}
Идентификатор конструктора должен совпадать с именем класса. У конструктора не указывается тип возвращаемого значения (даже void).
Для класса Massiv конструктор может быть объявлен так:
Massiv (int *b, int m)
{
n=m;
for (int i=0; i<n; i++)
a[i]=b[i];
}
Конструктор может иметь значения параметров по умолчанию.
Правила использования конструкторов:
- если конструктор не вызывается явно, то он вызывается автоматически при создании объекта с использованием значений параметров по умолчанию;
- если конструктор не описан явно, он генерируется транслятором автоматически.
Вызывать конструктор можно так:
имя_класса имя_объекта = имя_конструктора (список фактических параметров);
имя_конструктора имя_объекта (список фактических параметров);
Деструктор уничтожает объект класса и освобождает оперативную память, занимаемую его элементами данных. Деструктор представляет собой метод с именем, совпадающим с именем класса, перед которым стоит символ ~ (тильда). Деструктор не должен иметь ни параметров, ни типа возвращаемого значения.
Описание:
~имя_класса () {операторы;}
Например:
~Massiv () {};
Деструктор вызывается явно или неявно. Явно деструктор вызывается при необходимости уничтожения объекта.
Полиморфизм
Полиморфизм – многообразие форм. Это свойство, которое позволяет использовать одно имя для обозначения различных действий для одного или нескольких родственных классов.
К формам полиморфизма в С++ относятся:
- перегрузка функций и операций;
- виртуальные функции;
- шаблоны – обобщение функций.
Перегрузка функций и операций – это статический полиморфизм, т.к. связи между функциями устанавливаются на этапе компиляции.
Перегрузка операций
С++ позволяет переопределить действие большинства операций так, чтобы при использовании с объектами конкретного класса они выполняли заданные функции. Это дает возможность использовать собственные типы данных точно так же, как стандартные. Обозначения собственных операций вводить нельзя.
При перегрузке унарной операции операндом является вызывающий класс.
При перегрузке бинарной операции в качестве первого операнда выступает вызывающий класс, второй операнд задается в качестве аргумента.
Синтаксис:
тип_результата operator операция(формальные_параметры);
Например,
Massiv operator +(int k);
Пример 2.Реализовать класс для операций над числами в системе счисления с основанием р (1<p<10). Решить задачу: Дан массив чисел в р-ичной системе счисления. Найти НОД этих чисел.
function changeProof(proofobj) { if (proofobj.style.display=='none') {proofobj.style.display='inline'} else {proofobj.style.display='none'} } Просмотреть листинг решения
// программа == Пример 2 == #include <iostream.h> #include <stdlib.h> #include <conio.h> #include <string.h> #include <time.h> #include <stdio.h> class syst_sch { int p; char *s; long s10; public: syst_sch() { s=(char*) malloc (256); } ~syst_sch() { free(s); } void printp() { cout<<"число в "<<p<<"-ной системе счисления: "<<s<<endl; } void print10() { cout<<"число в десятичной системе счисления: "<<s10<<endl; } void vvodp(); void vvod10(); void perevodpto10 (); void perevod10top (); // операции syst_sch operator +(syst_sch b); syst_sch operator -(syst_sch b); syst_sch operator *(syst_sch b); syst_sch operator /(syst_sch b); syst_sch operator %(syst_sch b); syst_sch operator =(syst_sch b); int operator !=(syst_sch b); int operator >(syst_sch b); }; void main () { int nArr, i; syst_sch x, b, c, arr[50], nod; cout << "введите количество элементов массива " ; cin >> nArr; cout << endl; for ( i=0; i<nArr; i++) { arr[i].vvodp(); } // нахождение наибольшего общего делителя nod = arr[0]; for (i=1; i<nArr; i++) { x=arr[i]; while (x !=nod) if (x>nod) x -= nod; else nod=nod-x; } cout << "наибольший общий делитель чисел массива равен " <<endl; nod.printp(); nod.print10(); getch(); } void syst_sch :: vvodp() { cout<<"введите p (основание системы счисления): "; cin>>p; cout<<"вв.число в р-ной системе счисления: "; cin >>s; perevodpto10 (); } void syst_sch :: vvod10() { cout<<"введите p (основание системы счисления): "; cin>>p; cout<<"вв.число в десятичной системе счисления: "; cin >>s10; perevod10top (); } void syst_sch :: perevodpto10 () { int i=0; s10=0; while (s[i] != '\0') { s10 = s10*p+s[i]-'0'; i++; } } void syst_sch :: perevod10top () { int i=0; long vsp = s10; int st=1; while (st < s10) { st *= p; i++; } s[i]='\0'; i--; while (vsp) { s[i] = vsp%p+'0'; vsp /= p; i--; } } syst_sch syst_sch :: operator = (syst_sch b) { p = b.p; s10 = b.s10; int i=0; while (b.s[i] != '\0') {s[i] = b.s[i]; i++; } s[i] = b.s[i]; return *this; } syst_sch syst_sch :: operator +(syst_sch b) { int n, q, vsp; syst_sch c; c.p=p; c.s10=s10+b.s10; c.perevod10top(); return c; } syst_sch syst_sch :: operator -(syst_sch b) { int n, q, vsp; syst_sch c; c.p=p; c.s10=s10-b.s10; c.perevod10top(); return c; } syst_sch syst_sch :: operator *(syst_sch b) { int n, q, vsp; syst_sch c; c.p=p; c.s10=s10*b.s10; c.perevod10top(); return c; } syst_sch syst_sch :: operator /(syst_sch b) { int n, q, vsp; syst_sch c; c.p=p; c.s10=s10/b.s10; c.perevod10top(); return c; } syst_sch syst_sch :: operator %(syst_sch b) { int n, q, vsp; syst_sch c; c.p=p; c.s10=s10%b.s10; c.perevod10top(); return c; } int syst_sch :: operator !=(syst_sch b) { return s10!=b.s10; } int syst_sch :: operator >(syst_sch b) { return s10>b.s10; } |
Пример 3. Описать класс для работы с неотрицательными длинными числами и реализовать следующие операции:
- ввод числа;
- вывод длинного числа;
- операции отношения для длинных чисел;
- сложение;
- вычитание;
- умножение;
- деление.
function changeProof(proofobj) { if (proofobj.style.display=='none') {proofobj.style.display='inline'} else {proofobj.style.display='none'} } Просмотреть листинг решения
#include <iostream.h> #include <stdlib.h> #include <string.h> #define MaxN 2000 typedef int DlCh[MaxN]; class DC { DlCh a; void per(); public: void Nul(); int KTs(); DC operator +(DC b); /* сложение */ DC operator =(DC b); /* присваивание */ DC operator *(DC b); /* умножение */ DC operator *(long b); /* умножение на короткое*/ void vvod(); void Print(); }; void main() {DC a, b, c, d; int n; /*a.vvod(); b.vvod(); c=a+b; c.Print(); int n=100; d=a; */ cout<<"n?"; cin >> n; d.Nul(); d.vvod(); for (int i=1;i<=n;i++) d=d*n; d.Print(); } /* Обнуление длинного числа */ void DC::Nul() { for (int i=0;i<MaxN;i++) a[i]=0; } /* Ввод длинного числа в виде строки и преобразование его в массив цифр */ void DC::vvod() { char sa[MaxN]; cout <<"Введите длинное число: " << endl; cin >> sa; Nul(); int n=strlen(sa); for (int i=0;i<n;i++) a[i]=sa[n-i-1]-'0'; } /* Определение количества цифр в записи длинного числа */ int DC::KTs() {int i; for (i=MaxN-1; i>0&&a[i]==0;i--); return i+1; } int maxi(int a, int b) { if (a>b) return a; else return b; } /* Операция сложения */ DC DC::operator +(DC b) {int n, Vsp, p; DC c; c.Nul(); n=maxi(KTs(), b.KTs()); p=0; for (int i=0; i<=n; i++) {Vsp=a[i]+b.a[i]+p; p=Vsp/10; c.a[i]=Vsp%10;} return c; } DC DC::operator *(DC b) /* умножение */ {int m, n, Vsp, p; DC c; c.Nul(); m=KTs(); n=b.KTs(); for (int i=0; i<m; i++) { p=0; for (int j=0; j<n; j++) {Vsp=a[i]*b.a[j]+p+c.a[i+j]; c.a[i+j] = Vsp%10; p= Vsp/10; } c.a[i+n]=p; } return c; } DC DC::operator =(DC b) /* присваивание */ { for(int i=0;i<MaxN;i++) a[i]=b.a[i]; return *this; } /* Вывод длинного числа */ void DC::Print() { for (int i=KTs()-1;i>=0;i--) cout<<a[i]; cout<<"\n"; } DC DC::operator *(int b) /* умножение */ {int m, n, Vsp, p; DC c; c.Nul(); p=0; for (int i=0;i<=KTs()-1;i++) {Vsp=a[i]*b+p; c.a[i]= Vsp%10; p=Vsp/10;} i=KTs(); while (p) {c.a[i]=p%10; p/=10; i++;} return c;} |