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

unique_ptr - dwukrotne wywołanie destruktora obiektu

Object Storage Arubacloud
0 głosów
155 wizyt
pytanie zadane 19 października 2020 w C i C++ przez Patelniaszczy Nowicjusz (170 p.)

Cześć, mam małe pytanko odnośnie unique_ptr, ponieważ z natury jestem niezbyt ufny więc lubię moje informację potwierdzać w kilku źródłach :)

Jestem w trakcie odbywania pewnego kursu związanego z programowaniem w C++ i pojawiły się tam pewne formy tworzenia obiektów przy pomocy smart pointerów. Mając załóźmy prostą klasę A:

class A
{
  public:
  A()
  {
    cout<<"ctor"<<endl;
  }
  string value{"test"};
  ~A()
  {
    cout<<"dtor"<<endl;
  }
};

gdy chcemy dynamicznie alokować obiekt takiej klasy przy pomocy np. unique_ptr, taka wersja:

unique_ptr<A> ptr(new A);

z tego co mi mówili prowadzący jest błędna, ze względu na to że obiekt jest dwukrotnie alokowany, raz przy użyciu operatora new, i raz dzięki unique_ptr. Przy czym jako poprawną formę przytaczają:

unique_ptr<A> ptr(make_unique<A>());

Czy przy obecnych kompilatorach stanowi to jakąś różnicę? Prosiłbym o jakiś komentarz odnośnie tego.

Kolejne moje pytanie odnosi się do dziwnego tworu, mianowicie:

unique_ptr<A> ptr(make_unique<A>(A()));

Co ja właściwie alokuje w taki sposób? Czy to jest w ogóle poprawne?

Z tego co widzę destruktor klasy A wywołuje się dwukrotnie:

ctor
dtor
dtor

Pozdrawiam.

komentarz 19 października 2020 przez tkz Nałogowiec (42,000 p.)

gdy chcemy dynamicznie alokować obiekt takiej klasy przy pomocy np. unique_ptr, taka wersja:

1

unique_ptr<A> ptr(new A);

z tego co mi mówili prowadzący jest błędna, ze względu na to że obiekt jest dwukrotnie alokowany, raz przy użyciu operatora new, i raz dzięki unique_ptr.

Kompilator sądzi inaczej: http://cpp.sh/8libsb

https://en.cppreference.com/w/cpp/memory/unique_ptr spójrz na dostępne konstruktory, oraz co przyjmuje i co zwraca make_uniqie

komentarz 19 października 2020 przez j23 Mędrzec (194,920 p.)

@Patelniaszczy,

taka wersja: (...) z tego co mi mówili prowadzący jest błędna. ze względu na to że obiekt jest dwukrotnie alokowany,

Fajnych masz prowadzących :)

1 odpowiedź

+1 głos
odpowiedź 19 października 2020 przez tangarr Mędrzec (154,860 p.)
wybrane 19 października 2020 przez Patelniaszczy
 
Najlepsza

Szablon make_unique to tylko cukier syntaktyczny. Dla kompilatora nie ma różnicy między wywołaniami 1 i 2

Spójrz na przykładową implementację make_unique

template<class T, class... Args>
std::enable_if_t<!std::is_array<T>::value, std::unique_ptr<T>>
make_unique(Args&&... args)
{
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

Ten szablon powstał prawdopodobnie dlatego, żeby oduczyć programistów jawnego używania słów kluczowych new i delete.

Aby dowiedzieć się co się dzieje w ostatnim przykładzie musisz uruchomić poniższy kod.

#include <iostream>
#include <memory>

using namespace std;

class A
{
public:
    A() {
        cout<<"konstruktor" <<endl;
    }
    A(const A &a) {
        cout<<"konstruktor kopiujacy" <<endl;
    }
    A(A &&a) {
        cout<<"konstruktor przenoszacy " <<endl;
    }
    ~A() {
        cout<<"destruktor " <<endl;
    }
};

int main()
{
   unique_ptr<A> ptr(make_unique<A>(A()));
   cout  << "Koniec funkcji main";
}

Na początku tworzysz obiekt A na stosie. Przekazując go do make_unique tak na prawdę używasz go jako argument dla operatora new.

new A(obiekt_klasy_A)

Kompilator na podstawie kontekstu decyduje którego konstruktora użyć (kopiującego czy przenoszącego). Po wykonaniu tej linii kodu oryginalny obiekt klasy A nie jest już potrzebny i zostaje zniszczony. Skopiowany obiekt zostanie zniszczony przy wyjściu z zakresu funkcji main.
 

Podobne pytania

0 głosów
2 odpowiedzi 305 wizyt
pytanie zadane 12 sierpnia 2021 w C i C++ przez Pawel1995 Gaduła (3,810 p.)
0 głosów
2 odpowiedzi 237 wizyt
+1 głos
2 odpowiedzi 652 wizyt

92,575 zapytań

141,424 odpowiedzi

319,649 komentarzy

61,960 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

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy 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!

...