Jak sprawdzić czy dynamiczna zmienna istnieje c++

0

mam ciekawy problem :

  1. mam klasę .
  2. tworze dynamicznie zmienną dla tej klasy.
  3. tworze drugi wskaźnik na tę zmienną powyżej
  4. za pomocą pierwszego wskaźnika usuwam klasę

pozostaje mi drugi wskaźnik na obiekt który już nie istnieje i nie wiem w jaki sposób przeciążyć operator porównania by dało się dowiedzieć czy obiekt jeszcze istnieje:

if(*wskaźnik==NULL)
{
// nie można wykonać operacji bo obiektu nie ma
return 0;
}
0

Usuwasz klasę? A może jakiś obiekt tej klasy?... Tworzysz dynamicznie jakąś zmienną, czy obiekt tej klasy?

To proste. Nie da sie tego zrobić. Masz wskaźnik na jakieś miejsce w pamięci. Co wiecej próba dereferencji tego wskaźnika może się skończyć jakimś segmentation faultem.
Moim zdaniem popełniłes jakiś bląd podczas planowania. Napisz troche wiecej o tym po co ci ten 2 wskaźnik.
Ogólnie jak kasujesz jakiś obiekt dynamiczny to dobrze jest ustawić wskaźniki które na niego pokazywały od razu na NULL żeby uniknąć problemów tego typu.

0

nie jesteś tego w stanie sprawdzić w normalny sposób - to jest po sprawdzaniu wskaźników których nie wyzerowałeś. pomóc moze std::auto_ptr

0

auto_ptr pasuje tu jak pięść do oka.
jak już jakiś mądry wskaźnik to boost::shared_ptr (jeśli nie przekręciłem nazwy)

0

@MarekR22: dokładnie, post swój puszczałem z nieodświeżonej strony.

Jeśli dokładnie znamy sytuację autora, to nie auto_ptr, a jakiś shared_ptr z boosta będzie potrzebny - ogólnie jakiś zliczający referencje. Jeśli cię ciekawi, jak to się w zarysie realizuje, to rzuć okiem sobie na plik
counted_pointer.hpp.

Kod używający go wyglądałby mniej więcej tak:

#include <iostream>
#include "counted_pointer.hpp"

using namespace std;

struct MyObject {
    int value;
    MyObject(int v) : value(v) { cout << "T(" << value << ")" << endl; }
    ~MyObject() { cout << "~T" << endl; }
    };

int main() {
    memory::safe_ptr<MyObject> a,b;

    a = new MyObject(7);
    b = a;

    cout << (a ? a->value : -666) << endl;

    // usuwamy obiekt na siłę
    force_delete(a);

    if(b)
        cout << b->value << endl;
    else
        cout << -666 << endl;

    // te instrukcje nic nie zrobią
    force_delete(a);
    force_delete(b);

    return 0;
    }

a w ogóle, ponieważ użyliśmy safe_ptr, to WCALE nie musimy pamiętać o force_delete: jak znikną wszystkie wskaźniki to pamięć się zwolni. Można więc nawet jeszcze zabawniej:

int main() {
    memory::safe_ptr<MyObject> a,b;
    a = new MyObject(7);
    b = a;

    a = 0;
    cout << "---" << endl;

    // poniżej stanie się cud: zniknie ostatni pointer do MyObject(7)
    // efekt: ruszy do pracy jego destruktor
    b = new MyObject(16);
    cout << "---" << endl;

    return 0;
    }
0

Rani, szkoda tylko że ten kod nie lubi się ze standardem...

0

a c**** mu w dupę, w gcc pisałem ;]

dopisane:
sprawdziłem na pedantic, oprócz jednego połkniętego returna co jest nie tak?

0

Manfred, jak Ci tak z 'niezgodnością' źle to popraw.

0
Ranides napisał(a)

sprawdziłem na pedantic, oprócz jednego połkniętego returna co jest nie tak?
Podwójne podkreślenia są zarezerwowane dla kompilatora.

0

Manfred, paragraf na który się powołujesz:

ISO IEC 2003 napisał(a)

In addition, some identifiers are reserved for use by C + + implementations and standard libraries (17.4.3.1.2) and shall not be used otherwise

ISO IEC 2003 17.4.3.1 napisał(a)

Reserved names:
[...]
The C + + Standard Library reserves the following kinds of names:
— Macros
— Global names
— Names with external linkage

Moje nazwy są namespace'owane, zagnieżdżone w klasie, nie zawracają gitary linkerowi.

Wewnątrz swojego namespace'a mogę używać dowolnych identyfikatorów.

0

Argh. Fakt, przepraszam za zamieszanie. Ale nie byłbym sobą gdybym nie stwierdził że __super jest keywordem visuala, więc on będzie miał z tym kodem problem.

0

No fakt, nie byłbyś sobą, gdybyś nie pominął najważniejszej rzeczy ;]
To znaczy tego, że Visual ma magiczną opcję "Disable Language Extensions".

  1. i teraz możemy mówić o standardzie

  2. a zresztą zrób se "find & replace"

  3. czyż nie napisałem "się w zarysie realizuje" ? Daję przykład kodu, który de facto może być używany, ale nie jest to kod biblioteczny. W bibliotecznych to na pierwszej pozycji ląduje plik "library_config.h" , a później makro makrem pogania. Bo oprócz keyworda, to np Visual wypieprza kuriozalny warning nt. deklaracji throw (że i tak mu niepotrzebna za bardzo). To wszystko trzeba łatać, i jakieś rozszerzenia, w jakimś kompilatorze to nic ze standardem nie mają wspólnego.

Nie będę takiej sieczki do czytania ludziom dawał.

1 użytkowników online, w tym zalogowanych: 0, gości: 1