Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Zarządzanie pamięcią(ogolnie) (ale też odnośnie obiektów w grze) - parę pytań

Ostatnio zmodyfikowano 2014-05-07 13:26
Autor Wiadomość
pekfos
» 2014-05-03 22:35:05
shared_ptr<>, unique_ptr<>, weak_ptr<>. auto_ptr<> jest deprecated.
P-109231
Chlorek
» 2014-05-03 22:59:21
1. Z tego co mi wiadomo jawne wywoływanie destruktora to UB (szczególnie dziwna wydaje mi się sytuacja, w której najpierw wywołamy go sami, a potem jeszcze automatycznie się wywoła podczas niszczenia obiektu). Nawet jeśli to jest poprawne, jakie to ma zastosowanie? Podobna sytuacja z konstruktorem, który też da się w sumie wywołać... tylko po co?
2. Niby czemu shared_ptr, unique_ptr etc. są przestarzałe? Można to powiedzieć o auto_ptr, ale raczej nie o pozostałych.

#Edit
Dobra, olać punkt 2. - dopiero teraz zauważyłem, że wymieniłeś te dobre a potem po kropce napisałeś o auto_ptr. Roztargniony ja, przeczytałem post na szybko i źle zrozumiałem ;)
P-109237
Monika90
» 2014-05-04 00:02:45
Jawne wywołanie destruktora to nie jest UB. Byle by nie był wywołany więcej niż raz. Jest to potrzebne w implementacji takich klas jak std::vector, boost::optional czy boost::variant.
P-109244
Chlorek
» 2014-05-04 01:19:30
Właśnie dlatego napisałem o automatycznym niszczeniu obiektów wychodzących ze scope'a. Takie obiekty automatycznie mają wywołany destruktor podczas, gdy wcześniej mógł on już zostać wywołany i to jest właśnie zagrożenie. Nie wiem jak bardzo jest to wtedy niebezpieczne dla działania programu, ale zapewne należy unikać takiej sytuacji.

A skoro już o tym mówimy to jak można wywołać taki destruktor, a następnie sprawić by nie został on wywołany drugi raz automatycznie? Jest taka możliwość, czy też może zastosowanie tego wygląda zupełnie inaczej?
P-109246
pekfos
» 2014-05-04 11:13:55
Podobna sytuacja z konstruktorem, który też da się w sumie wywołać... tylko po co?
By utworzyć obiekt może?

A skoro już o tym mówimy to jak można wywołać taki destruktor, a następnie sprawić by nie został on wywołany drugi raz automatycznie? Jest taka możliwość, czy też może zastosowanie tego wygląda zupełnie inaczej?
A kiedy nie jest wywoływany automatycznie? Dynamiczna alokacja - destruktor jest wywoływany podczas zwalniania, więc w tym sensie nie automatycznie. Można wywołać konstruktor dla bloku danych i utworzyć tam obiekt. Np w std::vector<> - reserve() i resize() robią zupełnie co innego. I wtedy nie można dla tych obiektów wywołać delete, więc trzeba ręcznie wymusić sprzątanie.
P-109250
libed
» 2014-05-04 13:24:19
Placement new.

Np. masz klasę której sizeof() = 16 bajtów.
Np. alokujesz sobie 64 bajty, po czym dokładnie w tej puli pamięci tworzysz 4 obiekty tej klasy. W momencie gdy chcesz się ich pozbyć, zamiast delete jawnie wywołujesz destruktor dla każdego obiektu. Obiekty zostaje zniszczony ale wciąż masz do dyspozycji te same 64 bajty, które możesz wykorzystać dla kolejnych obiektów.

Zamiast alokować pamięć dla każdego obiektu z osobna, alokujesz raz pewną pulę i z niej korzystasz.
P-109265
Chlorek
» 2014-05-04 17:24:25
Ok, dzięki za wyjaśnienie. Z tym że odnośnie konstruktora NIEKTÓRE kompilatory pozwalają na taki oto kod:
C/C++
class Test
{
public:
    Test()
    {
    }
};

int main()
{
    Test x;
    x.Test::Test();
   
    return 0;
}

Przykładowo mingw32 v4.8.1 (domyślam się, że z GCC pod linuxem sytuacja wygląda tak samo, ale nie próbowałem) wyrzuca błąd
error: cannot call constructor 'Test::Test' directly
Natomiast Visual Studio zarówno 2010 jak i 2012 bez problemu to łykają.
Destruktor natomiast idzie wywołać na wszystkich tych kompilatorach bez problemu. Tak więc zastanawiam się nad tym co jest standardem a co nie, co powinno się robić a czego nie.
Znając Microsoft to domyślam się, że to oni naginają zasady, ale może to zwyczajnie mingw32 nie do końca wszystko wspiera (w stosunku do GCC jest jednak trochę okrojone).

Tak czy inaczej, jaki jest sens w wywołaniu konstruktora w taki sposób? Nie wiem, czy konstruktor pełni jakieś dodatkowe funkcje poza wypełnieniem jakiś danych w obiekcie, czy też może ma jakieś bardziej złożone zadanie, którego w kodzie nie widzimy. Jeśli ktoś mi to wyjaśni to będę wdzięczny (zawsze lepiej wiedzieć więcej ;) ).
P-109285
pekfos
» 2014-05-04 17:51:08
Konstruktor i destruktor powinny być wywoływane tylko raz.
P-109289
1 2 « 3 » 4
Poprzednia strona Strona 3 z 4 Następna strona