Chiama un distruttore esplicitamente in C++
Questo articolo spiegherà diversi metodi su come chiamare un distruttore in modo esplicito in C++.
Usa la notazione obj.~ClassName()
per chiamare esplicitamente una funzione distruttore
I distruttori sono funzioni speciali che vengono eseguite quando un oggetto esce automaticamente dall’ambito o viene eliminato da una chiamata esplicita dell’utente. Notare che queste funzioni sono generalmente utilizzate per liberare le risorse usate dall’oggetto dato. Anche se un distruttore può essere chiamato esplicitamente come funzione membro, non è necessario farlo. Nella maggior parte dei casi, in cui i membri dei dati della classe vengono allocati dinamicamente, può portare a una doppia liberazione delle risorse. Quest’ultimo scenario di solito produce una chiusura anomala del programma.
Nell’esempio seguente, mostriamo la nostra classe definita chiamata - MyClass
, che ha due costruttori e un metodo integrato per recuperare il valore dell’unico membro dei dati. Anche il distruttore è definito, e con i costruttori, stampano i messaggi corrispondenti nel flusso cout
per rendere più facile per noi indagare sul comportamento.
Si noti che il seguente codice di esempio stampa due messaggi del distruttore, uno dei quali viene attivato dalla chiamata esplicita dell’utente e l’altro viene chiamato automaticamente all’uscita dal programma. Sebbene, se il membro di dati MyClass
fosse stato assegnato con l’operatore new
nel costruttore, questo esempio avrebbe portato a una chiusura anomala del programma, probabilmente un doppio errore.
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;
class MyClass {
public:
explicit MyClass(string s) : str(std::move(s)) {
cout << "Constructor 1 executed\n";
}
MyClass(const MyClass& s) : str(string(s.str)) {
cout << "Constructor 2 executed\n";
}
~MyClass() { cout << "Destructor executed\n"; }
string& getString() { return str; };
private:
string str;
};
int main() {
MyClass str1("Hello There! ");
cout << endl;
cout << "str1: " << str1.getString() << endl;
cout << endl;
str1.~MyClass();
return EXIT_SUCCESS;
}
Produzione:
Constructor 1 executed
str1: Hello There!
Destructor executed
Destructor executed
In alternativa, possiamo vedere che la seguente versione del codice attiva lo stesso numero di funzioni costruttore / distruttore, che è essenzialmente l’idea alla base di questo concetto. Quindi, anche se l’ultimo esempio funziona senza errori, non è consigliabile chiamare esplicitamente i distruttori.
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;
class MyClass {
public:
explicit MyClass(string s) : str(std::move(s)) {
cout << "Constructor 1 executed\n";
}
MyClass(const MyClass& s) : str(string(s.str)) {
cout << "Constructor 2 executed\n";
}
~MyClass() { cout << "Destructor executed\n"; }
string& getString() { return str; };
private:
string str;
};
int main() {
MyClass str1("Hello There! ");
MyClass str2(str1);
cout << endl;
cout << "str2: " << str2.getString() << endl;
cout << endl;
return EXIT_SUCCESS;
}
Produzione:
Constructor 1 executed
Constructor 2 executed
str2: Hello There!
Destructor executed
Destructor executed
Un altro caso da considerare è quando l’oggetto classe viene allocato con l’operatore new
e prima dell’uscita del programma viene chiamato delete
sullo stesso oggetto. Nota che l’ultima istruzione cout
viene stampata dopo l’esecuzione della funzione descrittore, il che significa che il descrittore è stato invocato quando è stato chiamato l’operatore delete
.
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;
class MyClass {
public:
explicit MyClass(string s) : str(std::move(s)) {
cout << "Constructor 1 executed\n";
}
MyClass(const MyClass& s) : str(string(s.str)) {
cout << "Constructor 2 executed\n";
}
~MyClass() { cout << "Destructor executed\n"; }
string& getString() { return str; };
string* getStringAddr() { return &str; };
private:
string str;
};
int main() {
auto* str4 = new MyClass("Hello There! ");
cout << endl;
cout << "str4: " << str4->getString() << endl;
cout << endl;
delete str4;
cout << "exiting" << endl;
return EXIT_SUCCESS;
}
Produzione:
Constructor 1 executed
str4: Hello There!
Destructor executed
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook