Лекция 10 Класс как абстрактный тип. Подбельский гл. 9, Страуструп гл. Конструкторы и деструктор Конструкторы - это специальные функции-члены класса, предназначенные для инициализации данных-членов конкретного объекта данного класса. К. не имеют возвращаемого значения (даже void ). К. могут быть (и зачастую являются) перегруженными функциями. Но может быть только один К. с умалчиваемыми параметрами. Имя функции К. совпадает с именем класса. Соответствующий К. вызывается неявно всякий раз при определении объекта. Деструктор - это специальная функция-член класса, предназначенная для освобождения ресурсов, связанных с конкретным объектом данного класса. Д. не имеет возвращаемого значения (даже void) и формальных параметров. Д. не может быть перегруженной функцией. Именем функции Д. является ~Имя_класса. Д. вызывается неявно всякий раз при уничтожении объекта. Пример 10: Класс Tbl, реализация односвязного списка строк.
Пример 10.1: Определение конструкторов и деструктора класса Tbl #include class Tbl { public: Tbl(const Tbl&); Tbl(const char* ); Tbl(int=32); // конструктор с умалчиваемыми параметрами ~Tbl(); void print() const; private: char *name; int sz, len; }; void Tbl::print()const { // Это просто константная ф-ция-член cout.width(2); cout<<dec <<" SZ=="<<sz <<" LEN=="<<len <<" NAME=\""<<name<<"\" ptr=="<<hex<<int(name)<<endl; } Tbl::Tbl(const char *str) { sz=len=strlen(str); name = new char [++sz]; strcpy(name,str); }
Tbl::Tbl(int size) {// конструктор с умалчиваемыми параметрами sz = size; len = 0; name = new char [sz]; memset(name,0,sz); //N++; } Tbl::Tbl(const Tbl& t) { // К. копирования при инициализации sz = t.sz; len = t.len; name = new char [sz]; strcpy(name,t.name); } Tbl::~Tbl() { cout<<dec <<"delete sz=="<<sz <<" len=="<<len<<endl; delete [] name; // освобождение ресурсов } Пример 10.1: Определение конструкторов и деструктора класса Tbl (Продолжение).
Пример : Использование объектов класса Tbl int main() { Tbl t1("Time"), // Будет вызвана Tbl::Tbl(const char *str) t2(8), // Будет вызвана Tbl::Tbl(int size) t3; // Будет вызвана Tbl::Tbl(int size), size==32 t1.print(); t2.print(); t3.print(); Tbl t4=t1; // Будет вызвана Tbl::Tbl(const Tbl& t) t4.print(); return 0; } SZ==5 LEN==4 NAME="Time" ptr== SZ==8 LEN==0 NAME="" ptr==7708a0 SZ==32 LEN==0 NAME="" ptr==7708d0 SZ==5 LEN==4 NAME="Time" ptr== delete sz==5 len==4 delete sz==32 len==0 delete sz==8 len==0 delete sz==5 len==4 Будет напечатано: Деструкторы вызываются в порядке, обратном к порядку возникновения (определения) объектов, т.е t4, t3, t2 и t1
Статические члены класса Статические данные-члены класса не тиражируются с каждым объектом, т.е существуют в единственном экземпляре. На Ст. данные-члены распространяются все правила доступа. Ст. данные-члены хранятся отдельно от каждого объекта. Перед определением объектов данного класса Ст. данные-члены должны быть проинициализированы в глобальной области видимости. Пример 10.2: Добавим к классу Tbl счетчик объектов данного класса. class Tbl { public: //... staticint getN() const {return N;} private: //... static int N; }; Tbl::Tbl(const char *str) { //... N++; } // аналогично во всех остальных к-ах
Пример : Использование объектов класса Tbl со счетчиком. int Tbl::N=0; int main() { Tbl t1("Time"), t2(8), t3; cout<<"SIZEOF TBL=="<<sizeof(t1)<<endl; //... cout<<"N=="<<Tbl::getN()<<endl; // t2.getN() можно и так return 0; } SIZEOF TBL==12... SZ==5 LEN==4 NAME="Time" ptr== N==4 delete sz==5 len==4... Будет напечатано:
Указатель this При каждом вызове каждая функция член (кроме статических) неявно получает еще один параметр, который является константным указателем на объект данного класса, равен адресу того объекта, для которого вызвана эта функция, имеет зарезервированное имя this Пример 10.3: Использование this для построения односвязного списка из объектов класса Tbl class Tbl { public: //... void add(){this->next=top; top=this;}// Ф-ия добавления эл-тов в начало списка void lprint(); // Ф-ия последовательной печати эл-тов списка private: //... Tbl* next; static Tbl *top; }; void Tbl::lprint() { if (!top) cerr<<"List is empty\n"; else { Tbl *temp=top; while(temp) { cout name; temp=temp->next; } cout<<endl; }
Пример : Использование объектов класса Tbl для построения списка. int Tbl::N=0; Tbl* Tbl::top=0; int main() { Tbl t("Time "), i("is "), m("money."); i.lprint(); m.add(); i.add(); t.add(); i.lprint(); return 0; } Будет напечатано: List is empty Time is money. delete sz==7 len==6...