CPnHorror Temat założony przez niniejszego użytkownika |
[C++] Wskaźnik na destruktor » 2017-07-02 06:11:02 Witam przy pomocy wskaźników (tablicy wskaźników) utworzyłem obiekty "wrogowie", jest ich 10. Problem mój polega na wywołaniu destruktora (obiektów) nie usuwaniu wskaźników gdyż ilość wrogów jest ustalona z góry jako 10 co by ukrócić kod programu. próbowałem : void zniszcz_wrogow() { for( int zkz = 0; zkz < 10; zkz++ ) { wsk[ zkz ] = delete wrog(); } }
a także: void zniszcz_wrogow() { for( int zkz = 0; zkz < 10; zkz++ ) { wsk[ zkz ]->delete wrog(); } }
i również: void zniszcz_wrogow() { for( int zkz = 0; zkz < 10; zkz++ ) { wsk[ zkz ]->wrog::~wrog(); } }
FUNKCJA tworzenia 10-ciu obiektów "wrog" wygląda następująco: void losuj_wrogow() { int yyyy, xxxx; bool czy_zyje; string mmoomm; bool warunek_o; for( int zkz = 0; zkz < 10; zkz++ ) { warunek_o = false; do { xxxx =( rand() % 77 ) + 0; yyyy =( rand() % 22 ) + 0; mmoomm = map[ xxxx ][ yyyy ]; if( mmoomm[ mmoomm.length() - 1 ] != '0' && wartosc_koloru_pola( map[ xxxx ][ yyyy ] ) != bezpieczny_kolor ) { warunek_o = true; } } while( warunek_o != true ); if( zkz < ile_wrogow ) { czy_zyje = 1; } else { czy_zyje = 0; } wsk[ zkz ] = new wrog( xxxx, yyyy, czy_zyje ); } }
być może " nie rozumiem " w pełni tego co zrobiłem ale przy tworzeniu stworzyłem tablicę wskaźników (wsk) na obiekty które zaś przetwarzam przy pomocy pętli (oczywista oczywistość), po przejściu z mapki na kolejną mapkę usuwam obiekty i chcę zmienić wartości tablicy wskaźników na nowe obiekty itd itd. wydaje mi się, że tylko źle wywołuję destruktor. naprostujcie mnie proszę o góru c++ :-) |
|
carlosmay |
» 2017-07-02 10:13:49 #include <iostream>
class Foo { public: Foo() { } ~Foo() { } void Method() { std::cout << "Method()\n"; } };
int main() { Foo * fptr = new Foo(); fptr->Method(); delete fptr; fptr = nullptr; } Zainteresuj się: vectorinteligentnymi wskaźnikami |
|
Kinexity |
» 2017-07-02 10:22:20 Muszę przyznać - dużo w tym fantazji, ale pozwól, że pomogę. Delete nie używamy, jak new - w sensie konstrukcja wskaznik = delete[ typ ]() jest bez sensu. Komputer nie musi znać typu usuwanej zmiennej, ponieważ on po prostu (z tego co mi wiadomo) oznacza daną część pamięci jako wolną - wystarczy, że wie ile ma zwolnić, a nie musi wiedzieć co ma zwolnić. Zgodnie z moim doświadczenie destruktor można wywołać po prostu tak wskaznik->~[ typ ]() i to powinno zadziałać. +Taka mała porada - w warunku pętli zamiast warunek_o != true , lepiej wstawić !warunek_o (lepiej wygląda i łatwiej się czyta ;D ). |
|
jankowalski25 |
» 2017-07-02 10:31:39 Jak już carlosmay wcześniej napisał, przecież wystarczy: delete wskaznik; wskaznik = nullptr; A jak masz tablicę, to zamiast wskaznik wstawiasz tablica[ indeks ] . Zgodnie z moim doświadczenie destruktor można wywołać po prostu tak wskaznik->~[ typ ]() i to powinno zadziałać. |
Z jakiego powodu chcesz ręcznie wywoływać destruktor? Używasz placement new? I po co te nawiasy kwadratowe przy typie? |
|
CPnHorror Temat założony przez niniejszego użytkownika |
» 2017-07-02 10:35:11 przepraszam uprzejmie, problem był nad wyraz głupi, po zaparzeniu kawy oraz wybudzeniu neuronów począłem myśleć a problem był następujący. destruktor (złe): destruktor (poprawne): to ten średnik namieszał, bez średnika wszystko działa. pewnie kompilator dzięki średnikowi uznał destruktor za osobną klasę... dziękuję wszystkim za odpowiedź :-) |
|
jankowalski25 |
» 2017-07-02 10:40:49 pewnie kompilator dzięki średnikowi uznał destruktor za osobną klasę... |
Prędzej linker stwierdził, że destruktor jest niezdefiniowany. Niemniej jednak bez konkretnego logu kompilacji nie można tego stwierdzić na pewno. W każdym razie lepiej nie wywoływać ręcznie destruktora, jeśli nie ma takiej potrzeby. Jak już zostało napisane wcześniej, najprościej wywołać delete na wskaźniku, a następnie przypisać mu wartość nullptr . |
|
Kinexity |
» 2017-07-02 11:06:57 @jankowalski25 - nawiasy kwadratowe wstawiłem bo tak uznałem, że będzie lepiej (chociaż w rzeczywistości ich nie używam, żeby nie było) - napisałem o ręcznym wywołaniu destruktora, ponieważ z tego co autor tematu na początku napisał zrozumiałem, że właśnie tego dotyczy problem (chociaż sam temat na to nie wskazuje) |
|
carlosmay |
» 2017-07-02 11:22:23 Przykład z użyciem std::vector#include <iostream> #include <vector> #include <string>
class Enemy { public: Enemy( std::string const & en ) : enemyName { en } { } ~Enemy() { } void Method() { std::cout << "Method()\n"; } std::string const & GetEnemmy() const { return enemyName; } private: std::string enemyName; };
using Enemies = std::vector < Enemy >;
void AppendEnemy( Enemies & e ) { std::string enemyName; std::getline( std::cin, enemyName ); e.push_back( Enemy( enemyName ) ); }
Enemies::iterator RemoveEnemy( Enemies & e, Enemies::iterator it ) { return it = e.erase( it ); }
void ShowEnemies( Enemies const & e ) { for( auto const & el: e ) { std::cout << el.GetEnemmy() << '\n'; } }
int main() { Enemies enemies; AppendEnemy( enemies ); AppendEnemy( enemies ); AppendEnemy( enemies ); ShowEnemies( enemies ); auto it = enemies.begin() + 2; it = RemoveEnemy( enemies, it ); ShowEnemies( enemies ); } first enemy second enemy third enemy first enemy second enemy third enemy first enemy second enemy Nie opakowywałem tablicy wrogów w klasę zarządzającą dodawaniem i usuwaniem wrogów. Zadanie pozostawiam tobie :] napisałem o ręcznym wywołaniu destruktora |
Najlepiej tego unikać. Wywołanie destruktora zwykle jest wywoływane w chwili opuszczenia scopu, w którym urzęduje obiekt i może to powodować dwukrotne wywołanie destruktora dla jednego obiektu (błąd). |
|
« 1 » 2 |