nemirst Aprīlis 15, 2008 Author Share Aprīlis 15, 2008 auto_ptr laikam vektoros lietot ir slikti. Tas nekas, ja vektors satur objektu ar elementiem, kuriem izmers var mainities laika gaita? Link to comment Share on other sites More sharing options...
bubu Aprīlis 15, 2008 Share Aprīlis 15, 2008 Protams, ka nekas. Uztver vektoru kā parastu masīvu. Tikai ar tādu papildus bonusa fīču, ka šī masīva garums var patvaļīgi mainīties (dinamiskais masīvs). Un parastam masīvam tak ir pie kājas, kas notiek to saturošo objektu memberiem. Vai tur kautkas vairāk, vai mazāk.. Link to comment Share on other sites More sharing options...
nemirst Aprīlis 15, 2008 Author Share Aprīlis 15, 2008 Nelietojot delete, skatos, ka nekur netiek izsaukts apaksklases destruktors, kas ir pareizi. Tagad pameginasu papetit, kapec pareizi nevar destruktoru izsaukt. Link to comment Share on other sites More sharing options...
bubu Aprīlis 15, 2008 Share Aprīlis 15, 2008 (labots) Tu glabā/deleto virsklases tipa pointerus, bet īstenībā tie ir apakšklases tipa objektus? Ja tā, tad virsklases destruktoram obligāti jābūt virtuālam. Ir viens tāds nerakstīts likums - ja tev ir kaut viena virtuāla metode virsklasē, tad tā destruktoram arī obligāti jābūt virtuālam. Labots Aprīlis 15, 2008 - bubu Link to comment Share on other sites More sharing options...
nemirst Aprīlis 15, 2008 Author Share Aprīlis 15, 2008 (labots) Tu glabā/deleto virsklases tipa pointerus, bet īstenībā tie ir apakšklases tipa objektus? Ja tā, tad virsklases destruktoram obligāti jābūt virtuālam. Isti nesapratu.. Mana klasee ir definets pointeris uz citu klasi. To pat laikam nesauc par apaksklasi, vienkarsi klasee ir definets citas klases objekts. So citas klases objektu es veidoju savas klases konstruktora ar new operatoru un noradei pieskiru adresi. Savas klases destruktora, savukart, es dzesu ar delete so objektu. Vai tik nav kaut kadas problemas ar vektoru. Jo manas klases objekti tiek ieklauti vektora. Seit manas programmas kods: // Unit1.cpp std::vector<myclass1>myclass1objvector; void __fastcall TForm1::FormCreate(TObject *Sender) { myclass1objvector.reserve(3); for(int i=0; i<3; i++) myclass1objvector.push_back(myclass1()); } // myclass1.h class myclass1 { public: myclass2 *class2obj; myclass1() { class2obj = new myclass2(); } ~myclass1() { delete class2obj; } }; // myclass2.h class myclass2 { public: myclass2() { } }; Tiek izmesta kluda, kad veru ciet formu jeb, kad tiek izsaukts vektora destruktors un lidz ar to abu klasu destruktori. Pasekoju si koda konstruktoru/destruktoru izsauksanas secibu un ta nav tada ka vajadzetu but. Ta ir sada: 1. objekta konstruktors 1. objekta apaksobjekta konstruktors 1. objekta destruktors 1. objekta apaksobjekta destruktors 2. objekta konstruktors ... Tatad iznak, ka tiek izveidoti objekti un uzreiz izdzesti. Kapec ta? A, laikam tiek saglabata objekta kopija vektora un push_back parametrs tiek uzreiz izdzests - jeb izsaukts ta destruktors. Tas gan jau normali skaitas. Labots Aprīlis 15, 2008 - nemirst Link to comment Share on other sites More sharing options...
bubu Aprīlis 15, 2008 Share Aprīlis 15, 2008 Apakšklase ir pavisam kautas cits. class Apakshklase : Virsklase {... }; Tāda "apaškobjekta" jēdziena vispār nav. Problēma ar taviem class2obj pointeriem ir tāda, ka vektors taisa kopijas taviem objektiem. Tb nedrīkst vektorā likt tipus, kurus nevar normāli kopēt (ar operator = vai copy construktoru). Taču, kas notiek tev - piemēram copy-konstruktorā - tiek izveidots jauns myclass1 objekts. Tam jaunajam objektam tiek piešķirts class2obj pointeris uz to pašu myclass2 objektu, kas vecajā myclass1 objektā. Un tad vēlāk tiek dzēsts ārā šis vecais myclass1 objekts. Un rezultātā jaunajam myclass1 objektam ir invalīds class2obj pointeris, kurš pie tam vēlāk tiek dzēsts ar delete. Implementē copy-konstruktorus un piešķiršanas operatorus klasēm, kurās glabā pointerus, ja gribi lai tās var tikt kopētas. Vai arī - glabā vektorā pointerus uz myclass1 klases objektiem. Link to comment Share on other sites More sharing options...
nemirst Aprīlis 16, 2008 Author Share Aprīlis 16, 2008 (labots) A, laikam tiek saglabata objekta kopija vektora un push_back parametrs tiek uzreiz izdzests - jeb izsaukts ta destruktors. Tas gan jau normali skaitas. Tapec ari so es piemineju. Nebiju ieprieks iedomajies, ka tiek kaut kas kopets. Tagad skaidrs, kas jadara, paldies. Tavs ieteikums par pointeru glabasanu vektora skiet labaks par copy-constructor ieviesanu. Tada veida izvairos no liekas kopesanas. Sadi daru: std::vector<manaklase*>pVector; SaktFunkcija() { manaklase *pObj; pVector.reserve(skaits); for(int i=0; i<skaits; i++) { pObj = new manaklase(132); pVector.push_back(pObj); } } BeigtFunkcija() { for(int i=0; i<skaits; i++) delete pVector[i]; } Tagad man sagada problemas source/header failu organizesana. Nav nacies laikam veidot programmas ar vairakiem source failiem, turklat vel ar klasem. Builderi projektam ir Unit1.cpp fails un sim failam attiecigais headeris - Unit.h. Es nodeklareju klasi sava headeri - Mans.h. Klase izmanto vairakas savas funkcijas, kuras negribu rakstit ka inline funkcijas - definejot funkcijas klases kermeni. Sis funkcijas modifice definetas formas - Form1(kura defineta Unit1.cpp). Ja funkcijas tiek definetas klases kermeni, tad nav problemu tikt klat formas objektiem, bet, ja defineju tas arpus klases, tad ir problemas, jo izmet kaut kadu kludu runtaimaa. Tapec laikam ir kadas kludas pareizi veidojot savas klases funkcijas vai ieklaujot header failus, vai staistot source failus. Vai funkcijam vajadzetu but definetam .cpp faila? Un varbut var kads vel paskaidrot svarigas nianses organizejot programmas strukturu tiesi mana gadijuma. Labots Aprīlis 16, 2008 - nemirst Link to comment Share on other sites More sharing options...
bubu Aprīlis 16, 2008 Share Aprīlis 16, 2008 Tur viss ir ļoti vienkārši - C/C++ kompilators neko par .h failiem nezin. Tas kompilē tikai .cpp failus. Visas #include direktīvas tas apstrādā ar parastu copy&paste principu - tb .h failu saturu "iekopē" .cpp failos. Kļūdas runtaimā noteikti nevar rasties no nepareizas .h/cpp failu lietošanas. Ja nu vienīgi tu taisi static globālos mainīgos .h failā, kuru inklūdē vairākos cpp failos un uzskati, ka šis mainīgais būs viens vienīgs eksemplārs programmā (static pie globāla mainīgā/funkcijas nozīmē privātu eksemplāru kompilēšanas vienībā). Ja negribi funkcijas inlainā klases deklarācijā rakstīt, tad neraksti. Taisi tās attiecīgā headerfaila .cpp failā un nav problēmu. Link to comment Share on other sites More sharing options...
nemirst Aprīlis 16, 2008 Author Share Aprīlis 16, 2008 (labots) Man ir Unit1.cpp. Ieklauju savus headerus - class1.h un class2.h. Prieks class1 man nevajag nekadu cpp failu. Bet prieks class2.h es veidoju cpp failu - class2.cpp. class2.cpp es ieklauju failu - class2.h. Projektam pievienoju abus failus - class1.cpp un class2.cpp. Prieksnojauta saka prieksa, ka class2.h failam jaizskatas sadi: // class2.h class class2 { public: class2() { Funkcija1(); }; int Funkcija1(void); }; Savukart. class2.cpp sadi: // class2.cpp include "class2.h" int class2::Funkcija1(void) { Form1->Caption = "asdf"; return 0; } Vai tad es pareizi daru? Hm, ieklavu vel class2.cpp failaa lielo Unit1.h headeri, un aigaja viss ka nakas. Vai tas ir labs veids? Klase class1 deklaracijaa satur objektu no class2, tadel class1.cpp faila es noradu 2 headerus - class1.h, class2.h. Kapec izmet kludu kompilators, uzradot, ka nevar izveidot tada tipa objektu? ieklavu class1.h header failaa headeri class2.h. ta darit ir normali? Labots Aprīlis 16, 2008 - nemirst Link to comment Share on other sites More sharing options...
bubu Aprīlis 16, 2008 Share Aprīlis 16, 2008 Iekš h faila iekļaut citu h failu ir ļoti normāli. Bet grūti izsekot tam, ko un kur tu tur iekļauj.. Kapec izmet kludu kompilators, uzradot, ka nevar izveidot tada tipa objektu?Kādu precīzi kļūdu izmet? Link to comment Share on other sites More sharing options...
nemirst Aprīlis 16, 2008 Author Share Aprīlis 16, 2008 (labots) neatceros jau vairak, bet tagad viss strada, kad esmu ieklavis include failus include failaa. Tagad mani interese sads gadijums: *src1.cpp fails lieto includi inc1.h *inc1.h lieto includes a1.h un a2.h *src1.cpp failam ir nepieciesama gan inc1.h, gan a2.h include Vai ir normali, ja ieklauju src1.cpp faila tikai inc1.h headeri? Tadejadi, skatoties src1.cpp kodu, es neredzu visas includes, bet man jaskatas vel inc1.h, lai redzetu, ka src1.cpp izmanto ari a2.h includi. Tas man diez ko nepatik. Vai nevar kaut ka ari src1.cpp ieklaut a2.h includi, bet nodrosinaties pret headeru parklasanos? Vai ari ta darit butu greizi un viss ir normali tapat? A, un kluda bija par to, ka neatrod kompilators tadu tipu - manaklase2. manaklase2 objekts man bija definets deklarejot manaklase1(manaklase1.h header failaa). Es ieklavu manaklase2.h failu manaklase1.cpp faila, bet, acimredzot, vajag ieklaut so headeri manaklase1.h faila. Labots Aprīlis 16, 2008 - nemirst Link to comment Share on other sites More sharing options...
bubu Aprīlis 16, 2008 Share Aprīlis 16, 2008 Tas ir normāli no kompilatora skatupunkta. Taču parasti pieņemts inkludēt to a2.h failu arī tajā src1.cpp failā. Lai cilvēkam būtu vieglāk redzēt, no kuriem failiem šis konkrētais fails ir atkarīgs. Pret headeru pārklāšanos vienmēr vajag aizsargāties. To dara ar header guard'iem: #ifndef __MANA_FAILA_VAARDS_H__ #define __MANA_FAILA_VAARDS_H__ ... headera saturs #endif vai arī: #pragma once ... headera saturs Tas otrais strādā uz MSVC un GCC. Nezinu par citiem C/C++ kompilatoriem. Link to comment Share on other sites More sharing options...
nemirst Aprīlis 17, 2008 Author Share Aprīlis 17, 2008 Lieliski, sis bija tiesi tas, kas man vajadzigs. Paldies, bubu, tu esi labakais. Link to comment Share on other sites More sharing options...
Recommended Posts
Izveido kontu, vai pieraksties esošajā, lai komentētu
Jums ir jābūt šī foruma biedram, lai varētu komentēt tēmas
Izveidot jaunu kontu
Piereģistrējies un izveido jaunu kontu, tas būs viegli!
Reģistrēt jaunu kontuPierakstīties
Jums jau ir konts? Pierakstieties tajā šeit!
Pierakstīties tagad!