• 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?

Aruba Cloud VPS - 50% taniej przez 3 miesiące!
+2 głosów
256 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 (155,140 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 399 wizyt
0 głosów
2 odpowiedzi 961 wizyt
pytanie zadane 19 sierpnia 2020 w C i C++ przez lujasjeden Użytkownik (860 p.)
0 głosów
2 odpowiedzi 318 wizyt
pytanie zadane 14 sierpnia 2020 w C i C++ przez lujasjeden Użytkownik (860 p.)

93,185 zapytań

142,198 odpowiedzi

322,005 komentarzy

62,514 pasjonatów

Advent of Code 2024

Top 15 użytkowników

  1. 2127p. - dia-Chann
  2. 2092p. - Łukasz Piwowar
  3. 2079p. - Łukasz Eckert
  4. 2037p. - Tomasz Bielak
  5. 2006p. - rucin93
  6. 2005p. - Łukasz Siedlecki
  7. 1964p. - CC PL
  8. 1835p. - Adrian Wieprzkowicz
  9. 1785p. - Michal Drewniak
  10. 1744p. - rafalszastok
  11. 1684p. - Mikbac
  12. 1624p. - Anonim 3619784
  13. 1520p. - Marcin Putra
  14. 1480p. - ssynowiec
  15. 1365p. - Dawid128
Szczegóły i pełne wyniki

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

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...