• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Dlaczego destruktor wykonuje się 2 razy?

VPS Starter Arubacloud
+2 głosów
223 wizyt
pytanie zadane 5 kwietnia 2020 w C i C++ przez Daaa22 Dyskutant (8,250 p.)

Mamy taki kod

#include <iostream>
#include <vector>

using namespace std;

class Class
{
public:
    ~Class()
    {
        cout << 'x';
    }
};

int main()
{
    vector<Class>klasa;

    klasa.push_back( {} );

    return 0;
}

Jak go uruchamiam to pokazuje on "xx". Czyli mamy jeden obiekt którego destruktor wykonuje się 2 razy. Dlaczego tak się dzieje i czy można zrobić coś żeby destruktor wykonywał się tylko raz?

1 odpowiedź

+5 głosów
odpowiedź 5 kwietnia 2020 przez tangarr Mędrzec (154,780 p.)
wybrane 5 kwietnia 2020 przez Daaa22
 
Najlepsza

Żeby zobaczyć co się tak naprawdę dzieje musisz dodać troszkę więcej kodu
 

#include <iostream>
#include <vector>
 
using namespace std;
 
class Class
{
public:
    Class() {
        cout << "constructor " << this << endl;
    }
    Class(const Class &other) {
        cout << "copy constructor " << this << endl;
    }
    Class(Class &&other) {
        cout << "move constructor " << this << endl;
    }
    ~Class()
    {
        cout << "destructor " << this << endl;
    }
};
 
int main()
{
    vector<Class>klasa;
 
    std::cout << "Dodnie kopii przez push_back" << std::endl;
    klasa.push_back( {} );
    std::cout << "Koniec programu" << std::endl;
 
    return 0;
}

Output:

Dodnie kopii przez push_back                                                                                                                   
constructor 0x7ffce4fb4d3f                                                                                                                     
move constructor 0x903c20                                                                                                                      
destructor 0x7ffce4fb4d3f                                                                                                                      
Koniec programu                                                                                                                                
destructor 0x903c20

Najpierw tworzysz obiekt tymczasowy przy pomocy konstruktora domyślnego.
Następnie obiekt (jego zawartość) jest przenoszony do wektora z użyciem konstruktora przenoszącego. (Gdybyś użył zmiennej lokalnej zamiast tymczasowej to użyty by został konstruktor kopiujący).
Zmienna tymczasowa jest niszczona (pierwszy destruktor).
I na koniec (po wyjściu z zakresu zmiennej klasa) niszczony jest obiekt wewnątrz wektora.

Żeby uniknąć tworzenia tymczasowego obiektu możesz użyć metody emplace_back. Służy ona do konstrukcji obiektu bezpośrednio wewnątrz kontenera.
 

#include <iostream>
#include <vector>
 
using namespace std;
 
class Class
{
public:
    Class() {
        cout << "constructor " << this << endl;
    }
    Class(const Class &other) {
        cout << "copy constructor " << this << endl;
    }
    Class(Class &&other) {
        cout << "move constructor " << this << endl;
    }
    ~Class()
    {
        cout << "destructor " << this << endl;
    }
};
 
int main()
{
    vector<Class>klasa;
    // Rezerwujemy miejsce aby uniknąć przenoszenia wektora
    // w inne miejsce w pamięci
    // polecam przetestować również bez tej operacji
    klasa.reserve(2);
 
    std::cout << "Dodnie kopii przez push_back" << std::endl;
    klasa.push_back( {} );
    std::cout << "A teraz czas na emplace_back" << std::endl;
    klasa.emplace_back();
    std::cout << "Koniec programu" << std::endl;
 
    return 0;
}

Output z programu

Dodnie kopii przez push_back                                                                                                                   
constructor 0x7ffe2fd8673f                                                                                                                     
move constructor 0x10f6c20                                                                                                                     
destructor 0x7ffe2fd8673f                                                                                                                      
A teraz czas na emplace_back                                                                                                                   
constructor 0x10f6c21                                                                                                                          
Koniec programu                                                                                                                                
destructor 0x10f6c20                                                                                                                           
destructor 0x10f6c21

 

Podobne pytania

0 głosów
0 odpowiedzi 248 wizyt
0 głosów
2 odpowiedzi 455 wizyt
pytanie zadane 19 sierpnia 2020 w C i C++ przez lujasjeden Użytkownik (860 p.)
0 głosów
2 odpowiedzi 223 wizyt
pytanie zadane 14 sierpnia 2020 w C i C++ przez lujasjeden Użytkownik (860 p.)

92,454 zapytań

141,263 odpowiedzi

319,099 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...