210 likes | 415 Views
Създаване, Разрушаване, Копиране, Инициализиране на обекти. Създаване и разрушаване на обекти Автоматични обекти Създават се с деклариране във функция или блок (извиква се конструктор). Разрушават се след излизане от функция или блок (извиква се деструктор). Статични обекти
E N D
Създаване, Разрушаване, Копиране, Инициализиране на обекти Създаване и разрушаване на обекти • Автоматични обекти • Създават се с деклариране във функция или блок (извиква се конструктор). • Разрушават се след излизане от функция или блок (извиква се деструктор). • Статични обекти • Създават се с деклариране: а) извън функция; б) във функция, но с думата static. • Създават се преди началото на mainи се разрушават след края и. • Достъпни са за всички функции след декларацията им (а). • Достъпни са за функциите в или пред дефиницията на които са дефинирани (б).
Създаване, Разрушаване, Копиране, Инициализиране на обекти Създаване и разрушаване на обекти • Динамични обекти • Създават се в частта heap на паметта чрез new, който извиква конструктора. • Разрушават се чрез delete, който извиква деструктора.
Създаване, Разрушаване, Копиране, Инициализиране на обекти Създаване и разрушаване на обекти #include <iostream.h> 1/2 #include <stdlib.h> class test { int a,b; public: test(int,int); //конструктор ~test(); //деструктор }; tets::test(int k,int j) { a=k; b=j; cout<<”конструктор:”<<a<<” “<<b<<”\n”; } test::~test() { cout<<”деструктор:”<<a<<” “<<b<<”\n”; } test a(1,1); //статичен обект void f();//прототип на функция
Създаване, Разрушаване, Копиране, Инициализиране на обекти Създаване и разрушаване на обекти void main() 2/2 { test b(5,5); //автоматичен обект for(int j=1;j<=2;j++) test c(j,2*j); //автоматичен обект в блок test *p; p=new test(2,3); //динамичен обект if(!p) exit(1); delete p; f(); } void f() { static test d(6,7); }//статичен обект
Създаване, Разрушаване, Копиране, Инициализиране на обекти Създаване и разрушаване на обекти //при създаване на обекта а - статичен //при създаване на обект b - автоматичен //при създаване на обект c в блок //разрушаване на обект c //при създаване на обект c в блок //разрушаване на обект c //при създаване на обект р - динамичен //разрушаване на обект р //при създаване на обекта d - статичен //разрушаване на обект при излизане от main //разрушаване на обект при излизане от main //разрушаване на обект при излизане от main конструктор 1 1 конструктор 5 5 конструктор 1 2 деструктор 1 2 конструктор 2 4 деструктор 2 4 конструктор 2 3 деструктор 2 3 конструктор 6 7 деструктор 5 5 деструктор 6 7 деструктор 1 1
Създаване, Разрушаване, Копиране, Инициализиране на обекти Инициализация на обекти • По време на декларация – извиква се конструктор class point { int x,y; public: point(int a) { x = y = a; } . . . }; . . . point ob(3); или point ob=3;
Създаване, Разрушаване, Копиране, Инициализиране на обекти Инициализация на обекти • Инициализация с обект от същия клас • Ако в един клас явно не е дефиниран конструктор за присвояване, компилаторът автоматично създава такъв, в момента когато новосъздаден обект се инициализира с обекта, намиращ се от дясната страна на знака за присвояване. Този конструктор за присвояване се нарича конструктор за копиране. point::point(pointconst & r) { x = r.x; y = r.y; } Създава се конструкторпри: point p = q; point::point(point *this,pointconst & r) { this ->x = r.x; this ->y = r.y; }
Създаване, Разрушаване, Копиране, Инициализиране на обекти Инициализация на обекти • Инициализация с обект от същия клас • Класът няма член-променлива, която да е указател към динамична памет void main() { point ob(3); //извиква се конструктор point ob_new=ob; //чрезпобитово копиранена ob в ob_new }//без извикване на конструктор Разрушават се последователно и двата обекта: ob_new и ob при излизане от main чрез извикване 2 пъти на деструктор.
Създаване, Разрушаване, Копиране, Инициализиране на обекти Инициализация на обекти • Инициализация с обект от същия клас • Класът има член-променлива, която е указателкъм динамична памет class point {int x,y; char *text; public: point(int a) { x=y=a; text=new char[10]; cout << “текст:”; cin >> text; } ~point() { delete text; } }; void main() { point ob(3); //извиква се конструктор point ob_new = ob;//създава се нов обект с побитово копиране }
Създаване, Разрушаване, Копиране, Инициализиране на обекти Инициализация на обекти • Инициализация с обект от същия клас • Класът има член-променлива, която е указателкъм динамична памет При излизане от main се разрушава най-напред обект ob_new (включително и динамичната зона от 10 байта). След това трябва да се разруши обект ob. Появява се проблем от факта, че динамичната зона от 10 байта е вече освободена и се извежда съобщението: Null pointer assignment.
Създаване, Разрушаване, Копиране, Инициализиране на обекти Инициализация на обекти • Инициализация с обект от същия клас • Класът има член-променлива, която е указателкъм динамична памет • Проблемът произтича от побитовото копиране, което се осъществява с т.нар. Копиращ Конструктор по подразбиране. • Проблемът може да бъде разрешен със създаване на копиращ конструктор в класа, който да реализира следната възможност:
Създаване, Разрушаване, Копиране, Инициализиране на обекти Копиращ конструктор • Обикновен Конструктор се извиква винаги при създаването на обект. • Копиращ конструктор се използва в следните случаи: • При инициализация на обект с друг обект от същия клас • Създава се нов обект като копие на фактически параметър, предаван по стойност на функция. • Създава се нов обект като копие на върнатия по стойност резултат от функция.
Създаване, Разрушаване, Копиране, Инициализиране на обекти Копиращ конструктор • В случай, че в класа не е дефиниран копиращ конструктор, се използва копиращ конструктор по подразбиране, реализиращ побитово копиране. • В случаите на член-променливи, които са указатели е наложително класът да съдържа собствен копиращ конструктор, а не да ползва този по подразбиране.
Създаване, Разрушаване, Копиране, Инициализиране на обекти Копиращ конструктор • Общ вид на копиращия конструктор • Пример илюстриращ необходимостта от копиращ конструктор в случаите на: • Инициализация на обект с друг обект от същия клас • Създаване на нов обект като копие на фактически параметър, предаван по стойност на функция име_клас(const име_клас&име_обект_за_копиране) { //тяло на копиращия конструктор }
Създаване, Разрушаване, Копиране, Инициализиране на обекти Копиращ конструктор #include <iostream.h> 1/5 #include <stdlib.h> class test { int nbr; //брой елементи в динамичния масив int *v;//указател към началото на масива public: test(); //конструктор без параметри test(int);//конструктор с един параметър test(int, int *); //конструктор с два параметъра test(const test &from); //копиращ конструктор ~test();//деструктор void out(); }; test::test() { nbr=0; v=0; cout<<”Конструктор нулев масив\n”; } Дефиниране на клас Конструктор за нулев масив
Създаване, Разрушаване, Копиране, Инициализиране на обекти Копиращ конструктор Конструктор за масив инициализиран с 0 test::test(int n) 2/5 { v=new int[nbr=n];//резервира динамична памет за масива if(!v) exit(1); for(int i=0;i<n;i++) v[i]=0; cout<<”Конструктор на масив с “<<n<<” нулеви елемента\n”; } test::test(int n,int *data) { v=new int[nbr=n];//резервира динамична памет за масива if(!v) exit(1); for(int i=0;i<n;i++) v[i]=data[i]; cout<<”Конструктор на инициализиран масив с“<<n<<” елемента\n”; } Конструктор за масив инициализиран с масив - параметър
Създаване, Разрушаване, Копиране, Инициализиране на обекти Копиращ конструктор Копиращ конструктор test::test(const test &from)3/5 { v=new int[from.nbr]; //резервира динамична памет за масива if(!v) exit(1); //за нов обект с брой елементи на //копирания for(int i=0;i<from.nbr;i++) v[i]=from.v[i];//копиране от from nbr=from.nbr; cout<<”Копиращ конструктор\n”; }
Създаване, Разрушаване, Копиране, Инициализиране на обекти Копиращ конструктор Деструктор test::~test() 4/5 { if(v)delete []v; //освобождава динамичната памет v=0; nbr=0; cout<<”Деструктор\n”; } void test::out() { for(int i=0;i<nbr;i++) cout<<*v++<<” ”; cout<<”\n”; } void f(test b) { cout<<”Извикване на функция\n”; } Функция за извеждане Функция с параметър обект, предаван по стойност
Създаване, Разрушаване, Копиране, Инициализиране на обекти Копиращ конструктор void main() 5/5 { test a(10);//създава се масив с 10 нулеви елемента a.out(); int array[]={1,2,3}; test b, c(3,array); b.out();//нулев масив – не се извежда нищо c.out(); test d(c); //c инициализира d (чрез копиращ конструктор) f(a); //ползва се копиращ конструктор }
Създаване, Разрушаване, Копиране, Инициализиране на обекти Копиращ конструктор Обект a Резултати от изпълнение Конструктор на масив с 10 нулеви елемента 0 0 0 0 0 0 0 0 0 0 Конструктор нулев масив Конструктор на инициализиран масив с 3 елемента 1 2 3 Копиращ конструктор Копиращ конструктор Извикване на функция Деструктор //разрушава копието във функцията Деструктор //разрушава d Деструктор //разрушава c Деструктор //разрушава b Деструктор //разрушава a Обект b Обект c Извеждане на b Извеждане на c c инициализира обект d Копие на фактически параметър
Създаване, Разрушаване, Копиране, Инициализиране на обекти Присвояване на обекти void main() { point ob(3); //извиква се конструктор point ob_new(6); //извиква се конструктор ob_new = ob;//чрезпобитово копиранена ob в ob_new //без копиращ конструктор (присвояване) } Разрушават се последователно и двата обекта: ob_new и ob при излизане от main чрез извикване 2 пъти на деструктор.