![]() |
![]() |
|
Programiranje Programski jezici, tehnike, alatke... |
![]() |
|
Alatke vezane za temu | Vrste prikaza |
![]() |
#61 |
Kekule Mekule
|
![]()
Elem jos jedno pitanje.
Imam recimo ovo: Kod:
BYTE* data = ilGetData(); delete data; P.S. Takodje ako imam neki takav pokazivac (npr. mCurrentGameState = mGameStates[0]), da li njega treba da brisem u destruktoru ili on to sam resava, s'obzirom da sam obrisao podatke gde treba. |
![]() |
![]() |
![]() |
#62 |
V.I.P. Programiranje
Član od: 29.8.2007.
Lokacija: Valjevo
Poruke: 1.349
Zahvalnice: 983
Zahvaljeno 371 puta na 280 poruka
|
![]()
Ne brisu se pokazivaci, oni samo "pokazuju" na odredjeno mesto u memoriji.
![]() Sa delete brises/oslobadjas samo sto kreiras sa new!!! U tvom slucaju treba da brines samo da ne koristis data pokazivac posle poziva na ilDeleteImage(). Posto vidim da si zaboravio: Kod:
int* p = new int[3];// rezervisan blok memorije za 3 int p // ovaj izraz je vrednost koju drzi pokazivac a to je adresa bloka memorije koju si kreirao sa new &p // i sam pokazivac oduzima memoriju, ovaj izraz je njegova adresa delete [] p; // oslobadjamo onaj blok memorije p = nullptr;// posto 'p' i dalje pokazuje na taj blok memorije postavljamo njegovu vrednost na 0 da se ne bi desila katastrofa ako se kojim slucajem zaboravi Poslednja ispravka: Belphegor (4.4.2012 u 20:05) |
![]() |
![]() |
![]() |
#63 |
Kekule Mekule
|
![]()
Nisam lepo formulisao mozda.
Ako imam vise pokazivaca koji pokazuju na isto i obrisem jednog, podaci su obrisani i svi su invalidirani? Kod:
Creep* c1 = new Creep(); Creep* c2 = c1; Creep* c3 = c2; delete c3; // c1 i c2 pokazuju na neko mesto u memoriji koje nije inicijalizovano? |
![]() |
![]() |
![]() |
#64 |
V.I.P. Programiranje
Član od: 29.8.2007.
Lokacija: Valjevo
Poruke: 1.349
Zahvalnice: 983
Zahvaljeno 371 puta na 280 poruka
|
![]()
Svi su "invalid" i bilo bi veoma opasno ako bi posle koristio jedan od njih.
![]() Kad pozoves delete onda oslobadjas onu kocku gde pise new Creep() a pokazivaci su i dalje zivi i pokazuju na isto mesto. EDIT: Evo ti prost primer: Kod:
int* p1 = new int(666); int* p2 = p1; int* p3 = p1; std::cout << "Adresa gde pokazuje p1 = " << p1 << std::endl; std::cout << "Adresa gde pokazuje p2 = " << p2 << std::endl; std::cout << "Adresa gde pokazuje p3 = " << p3 << std::endl; std::cout << "Adresa pokazivaca p1 = " << &p1 << std::endl; std::cout << "Adresa pokazivaca p2 = " << &p2 << std::endl; std::cout << "Adresa pokazivaca p3 = " << &p3 << std::endl; std::cout << "Vrednost sa adrese p1 = " << *p1 << std::endl; std::cout << "Vrednost sa adrese p2 = " << *p2 << std::endl; std::cout << "Vrednost sa adrese p3 = " << *p3 << std::endl; ... delete p1; p1 = nullptr; p2 = nullptr; p3 = nullptr; Poslednja ispravka: Belphegor (4.4.2012 u 21:11) |
![]() |
![]() |
Sledeći korisnik se zahvaljuje korisniku Belphegor na korisnoj poruci: | ||
Andross (4.4.2012) |
![]() |
#65 |
Član
Član od: 13.7.2009.
Poruke: 151
Zahvalnice: 67
Zahvaljeno 29 puta na 26 poruka
|
![]()
Je l' ima neka fora da prilikom citanja fajla otvorenog pomocu fopen() funkcije, skocim u sledeci red odnosno nakon procitanog <necega> predjem u novi red ignorisuci ostatak karaktera koji se nalazu u tom redu?
|
![]() |
![]() |
![]() |
#67 |
Kekule Mekule
|
![]()
1. Da li mogu elemente u unordered_map da brisem isto kao elemente u listi?
Kod:
std::unordered_map<std::string, Texture*> mTextures; // ... for(auto iter = begin(mTextures); iter != end(mTextures); iter++) delete *iter; |
![]() |
![]() |
![]() |
#68 |
Veteran
Član od: 27.12.2005.
Lokacija: Vremenske Grobnice, Hiperion
Poruke: 680
Zahvalnice: 99
Zahvaljeno 124 puta na 82 poruka
|
![]()
1. Brisanje bi izgledalo ovako:
Kod:
std::unordered_map<std::string, Texture*> mTextures; for(auto iter = begin(mTextures); iter != end(mTextures); iter++) { std::pair<std::string, Texture*>& current = *iter; delete current.second; } ![]() Kod:
typedef std::unordered_map<std::string, Texture*> MStrTexture; MStrTexture mTextures; for(auto iter = begin(mTextures); iter != end(mTextures); iter++) { MStrTexture::value_type& current = *iter; delete current.second; } Kod:
typedef std::unordered_map<std::string, Texture*> MStrTexture; MStrTexture mTextures; Texture* toBeDeleted; auto iter = begin(mTextures); for(; iter != end(mTextures); iter++) { MStrTexture::value_type& current = *iter; if(current.second == toBeDeleted) break; } if(iter != end(mTextures)) mTextures.erase(iter); Još jedna stvar. Ako imaš potrebu za operacijama ovog tipa, možda mape nisu dobro rešenje za problem koji pokušavaš da rešiš. Poslednja ispravka: M.Silenus (6.4.2012 u 0:02) Razlog: verzija sa std::remove_if ne radi! |
![]() |
![]() |
Sledeći korisnik se zahvaljuje korisniku M.Silenus na korisnoj poruci: | ||
Andross (6.4.2012) |
![]() |
#69 |
Veteran
Član od: 3.5.2008.
Lokacija: Beograd
Poruke: 760
Zahvalnice: 81
Zahvaljeno 213 puta na 144 poruka
|
![]()
Prošlo je skoro dva meseca od kako sam napisao onaj post. Red je da se osvrnem i malo razmislim.
Pogledao sam svež snimak govora Bjarna Stroustrupa o C++11. I sada sam siguran da su svi nedostaci C++-a loša sreća. Vreme u kome je Bjarn donisio važne odluke po jezik je bilo takvo da se nije moglo pretpostaviti kakve bi posledice to moglo da ostavi, jer je sve to bilo samo dodavanje novih stvari na C koji se već dokazao kao dobar. Računari su bili takvi da je previše pametovanja samo trošilo resurse procesora i memorije. Sa okolnostima kavi su bile i ciljevima postavljenim, bila je istorijska nužnost da ispadne ovako kako je ispalo. Šta da se radi. Brajn je uradio najbolje što je mogao u to vreme. Tek posle godina korišćenja su se videli neki nedostaci, koje su drugi ispravljali, ali Bjarn nije mogao da ih otkrije tada. Ispostavilo se da su ovo neke stvari koje moraju manje više da ostanu zakovane u jeziku i eto. Kudos Brajnu, i nadam se da će mi oprostiti. Ali ipak mislim da C++ nije baš kompletan. Za velike projekte pogodniji su C# ili Java, a za sistemsko prigramiranje C. |
![]() |
![]() |
![]() |
#70 |
V.I.P. Programiranje
Član od: 29.8.2007.
Lokacija: Valjevo
Poruke: 1.349
Zahvalnice: 983
Zahvaljeno 371 puta na 280 poruka
|
![]()
@Andross
Koristi shared_ptr i nema da te boli glava. |
![]() |
![]() |
![]() |
#71 | |
Kekule Mekule
|
![]() Kod:
for(auto iter = begin(mTextures); iter != end(mTextures); iter++) { std::pair<std::string, Texture*>& current = *iter; delete current.second; } Citat:
|
|
![]() |
![]() |
![]() |
#72 |
V.I.P. Programiranje
Član od: 29.8.2007.
Lokacija: Valjevo
Poruke: 1.349
Zahvalnice: 983
Zahvaljeno 371 puta na 280 poruka
|
![]()
Govori ti da ti fali const u:
Kod:
for(auto iter = begin(mTextures); iter != end(mTextures); iter++) { std::pair<const std::string, Texture*>& current = *iter; delete current.second; } Kod:
... delete (*iter).second; Kod:
map.insert( pair( string, new Texture) ); |
![]() |
![]() |
Sledeći korisnik se zahvaljuje korisniku Belphegor na korisnoj poruci: | ||
Andross (6.4.2012) |
![]() |
#73 |
V.I.P. Programiranje
Član od: 29.8.2007.
Lokacija: Valjevo
Poruke: 1.349
Zahvalnice: 983
Zahvaljeno 371 puta na 280 poruka
|
![]()
Evo ti primer sa std::shared_ptr, i zamenio sam unordered_map za list (isto unikatne texture) posto ionako ovde nije brzina bitna a list je dobar kad se brisu elementi random.
Kod:
#if defined(_MSC_VER) #include <vld.h> // Visual Leak detector #endif #include <iostream> #include <list> #include <string> #include <memory> #include <algorithm> class Texture; typedef std::shared_ptr<Texture> sp_texture; typedef std::list<sp_texture> l_texture; class Texture { private: std::string name; int* data; public: Texture() : name(""), data(new int(666)) { } ~Texture() { delete data; } bool loadFromFile(const std::string& n) { name = n; return true; } const std::string& getName() const { return name; } }; class TextureManager { public: static l_texture ltex; sp_texture load(const std::string& name) { Texture* tex = nullptr; try { const auto& end = ltex.end(); auto it = ltex.begin(); for(; it != end; ++it) { if((*it)->getName() == name) { return *it; } } tex = new Texture; if(!tex->loadFromFile(name)) { std::string errStr = "Failed to load texture: " + name; throw std::runtime_error( errStr ); } ltex.push_back(sp_texture(tex)); } catch( const std::runtime_error& e) { delete tex; throw e; } return ltex.back(); } }; l_texture TextureManager::ltex; void print_textures() { std::cout << "=========================" << std::endl; std::for_each(TextureManager::ltex.begin(), TextureManager::ltex.end(), [] (sp_texture t) { std::cout << t->getName() << std::endl; }); } void remove_texture(const std::string& name) { auto it = std::find_if(TextureManager::ltex.begin(), TextureManager::ltex.end(), [&name] (sp_texture t)->bool { return name == t->getName(); }); if(it != TextureManager::ltex.end()) { TextureManager::ltex.erase(it); } } int main() { try { TextureManager tm; tm.load("AbC"); tm.load("ABBC"); tm.load("ACC"); tm.load("ABBB"); tm.load("ABBB"); // duplikat, ali ga nece ucitati print_textures(); remove_texture("AbC"); print_textures(); remove_texture("ABBB"); print_textures(); { sp_texture tex = tm.load("Foo"); remove_texture("Foo"); // tex pokazuje na Foo ali je sigurno Texture& t = *tex.get(); std::cout << "t name = " << t.getName() << std::endl; } } catch(const std::runtime_error& e) { std::cerr << e.what() << std::endl; } return 0; } Kod:
#include <stdexcept> Poslednja ispravka: Belphegor (6.4.2012 u 2:01) Razlog: Obrisao neiskoriscene promenjljive iz koda |
![]() |
![]() |
![]() |
#74 |
Kekule Mekule
|
![]()
Resio sam to ovako (doduse ovo bi trebalo teoretski da radi, jos uvek nemam kod koji bi ovo testirao):
Kod:
#ifndef TEXTUREMANAGER_HPP_INCLUDED #define TEXTUREMANAGER_HPP_INCLUDED #include <IL/il.h> #include <string> #include <unordered_map> #include "Texture.hpp" class TextureManager { public: // Destructor ~TextureManager(); // Public methods static bool Initialize(); static void Shutdown(); bool LoadTexture(std::string filename); void UnloadTexture(std::string filename); Texture* GetByFilename(std::string filename); static TextureManager* GetInstance() { return mInstance; } private: // Member variables std::unordered_map<std::string, Texture*> mTextures; static TextureManager* mInstance; }; #endif // TEXTUREMANAGER_HPP_INCLUDED Kod:
#include "TextureManager.hpp" // Initialization of static members TextureManager* TextureManager::mInstance = nullptr; // Destructor TextureManager::~TextureManager() { // Delete all textures for(auto iter = begin(mTextures); iter != end(mTextures); iter++) delete (*iter).second; } // Method implementation bool TextureManager::Initialize() { // Abort if instance is already created if(mInstance != nullptr) return false; // Create the instance mInstance = new TextureManager(); // Initialize DevIL ilInit(); // Check the version of the library if(ilGetInteger(IL_VERSION_NUM) < IL_VERSION) return false; return true; } void TextureManager::Shutdown() { // Delete the instance delete mInstance; mInstance = nullptr; } bool TextureManager::LoadTexture(std::string filename) { // Check if the filename is empty string if(filename.empty()) return false; // Texture is already loaded if(mTextures.find(filename) != mTextures.end()) return true; // Generate one image name ILuint texId; ilGenImages(1, &texId); // Bind the image name ilBindImage(texId); // Try to load the image if(!ilLoadImage(filename.c_str())) return false; // Get the width and height int width = ilGetInteger(IL_IMAGE_WIDTH); int height = ilGetInteger(IL_IMAGE_HEIGHT); // Create our texture Texture* texture = new Texture(width, height, filename); // Copy pixel data into our texture ilCopyPixels(0, 0, 0, width, height, 1, IL_RGB, IL_UNSIGNED_BYTE, texture->GetData()); // Unbind the image and delete its data ilBindImage(0); ilDeleteImage(texId); // Store our texture mTextures[filename] = texture; return true; } void TextureManager::UnloadTexture(std::string filename) { // Try to find the texture auto iter = mTextures.find(filename); // Return if texture is not found if(iter == mTextures.end()) return; // Delete the texture and remove it delete (*iter).second; mTextures.erase(iter); } Texture* TextureManager::GetByFilename(std::string filename) { // Try to find the texture auto iter = mTextures.find(filename); // Return nullptr if texture is not found if(iter == mTextures.end()) return nullptr; return (*iter).second; } |
![]() |
![]() |
![]() |
#75 |
Član
|
![]()
Da ne bih lutao po forumu, imam jedno pitanje:
Imam nekog pocetnog iskustva sa C++ programskim jezikom. Da li mogu naci dovoljno teorije na internetu, ili da kupim neku knjigu a sa neta da upotpunjujem??? |
![]() |
![]() |
![]() |
#76 |
V.I.P. GNU/Linux
Član od: 1.11.2005.
Poruke: 11.131
Zahvalnice: 2.058
Zahvaljeno 4.911 puta na 2.848 poruka
|
![]()
Ja mislim da je bolje učiti po knjizi sistematično i redom, nego iz ko zna kakvih tutorijala bez plana.
|
![]() |
![]() |
Sledeći korisnik se zahvaljuje korisniku voodoo_ na korisnoj poruci: | ||
Nikola Stankovic (27.4.2012) |
![]() |
#77 |
Veteran
|
![]()
Imam pitanje, koristio sam:
void UpdateBullets(Bullet bullets[]) da li to znaci da kad koristim array kao parametar da u stvari 'dajem' adresu array-a kad pozivam f-ju: UpdateBullets(bullets); ?? |
![]() |
![]() |
![]() |
#78 |
Veteran
Član od: 27.12.2005.
Lokacija: Vremenske Grobnice, Hiperion
Poruke: 680
Zahvalnice: 99
Zahvaljeno 124 puta na 82 poruka
|
![]()
Bullets bullets[] je ekvivalent Bullets * bullets, tako da je odgovor na tvoje pitanje: da, niz šalješ po adresi.
|
![]() |
![]() |
Sledeći korisnik se zahvaljuje korisniku M.Silenus na korisnoj poruci: | ||
Ivan-94 (2.5.2012) |
![]() |
#79 |
Starosedelac
Član od: 5.12.2005.
Lokacija: Niš
Poruke: 1.259
Zahvalnice: 49
Zahvaljeno 154 puta na 115 poruka
|
![]()
Zašto mi nasleđivanje klase vraća LNK2019 grešku pri linkovanju?
Kod:
class ElementI : public Element |
![]() |
![]() |
![]() |
#80 |
Veteran
Član od: 27.12.2005.
Lokacija: Vremenske Grobnice, Hiperion
Poruke: 680
Zahvalnice: 99
Zahvaljeno 124 puta na 82 poruka
|
![]()
Verovatno nisi definisao podrazumevani konstruktor u klasi Element.
Podrazumevani konstruktor je konstruktor bez argumenata, u tvom slučaju Element::Element(void). Ako ne definišeš nijedan kostruktor, podrazumeva se da on postoji - aka, kompajler ga automatski definiše. On the other hand, ako definišeš neki ne-podrazumevani konstruktor, onda da bi imao i podrazumevani, moraš i njega da definišeš. Na primer: Kod:
class Element { public: Element(int i); // vise nema podrazumevanog konstruktora }; class ElementI : public Element { double x; public: ElementI(double x_) : x(x_) {} }; Tj. kompajler generiše ovo: Kod:
class ElementI : public Element { double x; public: ElementI(double x_) : Element(), x(x_) {} }; Rešenje: definiši Element::Element(), ili eksplicitno pozovi neki od definisanih konstruktora za Element. Čak bih ti predložio da uvek sam pozivaš kostruktore bazne klase, tako si uvek znaš šta se poziva - pogotovo ako nisi baš načisto sa tim šta je podrazumevana akcija u tom slučaju. BTW. ako ti kompajler podržava C++11, i ako ti je podrazumevana implementacija podrazumevanog konstruktora odgovarajuća (ona samo poziva podrazumevane konstruktore svojih polja), onda možeš da uradiš ovo: Kod:
class Element { public: Element() = default; Element(int i); // vise nema podrazumevanog konstruktora }; |
![]() |
![]() |
![]() |
Bookmarks sajtovi |
Tagovi |
c++, how to, pomoc, programiranje |
Alatke vezane za temu | |
Vrste prikaza | |
|
|