Hello stackOverflow friends, I am studying OOP and the following problem arose: I have a class with two attributes, one of type string and the other of type int, when I create an object I show its data on the screen and then I call the destructor. To confirm the deletion of the object, I call the method again to show the data of the object and it turns out that only the information of the string is deleted. I don't know if I'm missing something with the destructor or if I'm just doing it all wrong. Here the code:
#include<iostream>
#include<cstdlib>
using namespace std;
class Persona
{
public:
Persona(string,int);
~Persona();
void mostrarPersona();
private:
string nombre;
int edad;
};
Persona::Persona(string _nombre, int _edad)
{
nombre = _nombre;
edad = _edad;
}
Persona::~Persona()
{
}
void Persona::mostrarPersona()
{
cout << "\tNombre: " << nombre << endl;
cout << "\tEdad: " << edad << endl;
}
int main() {
system("color 1F");
Persona p1("Luis Miguel", 45);
p1.mostrarPersona();
p1.~Persona();
p1.mostrarPersona();
system("pause");
return 0;
}
I think you have a misunderstanding with what it means to destroy an object.
In C++, destroying an object just involves calling its destructor . That is to say, it does not imply absolutely anything in relation to the management of its own resources .
Additionally, C++ guarantees that calling a destructor will implicitly call the destructor of its member-variables.
In other words: the destruction of an object does not imply that changes are made in memory . It is a system to use to free resources (memory blocks, unlink from possible related instances, ...).
There is the solution to your question: when destroying your instance, the destructors of its member-variables are called, namely:
The first is a
std::string
, which does have a non-trivial destructor (we'll save that for another time). This destructor is invoked, and the tasks located on it are performed. Specifically, it frees up the memory used by thestd::string
.Below you have a
int
. It is a primitive type, with a trivial destructor . In this case, that destructor is ignored . Although for theoretical purposes it can be considered that it is actually invoked, for practical purposes absolutely nothing happens .And that's it. The memory remains as it was left by successive destroyers summoned. In the case of
std::string
, it records that it has no memory block in use (that's why it appears as empty ). In the case ofint
, absolutely nothing is done, and the last value it had appears.By the way, calling the destructor more than once is undefined behavior , so strange things can happen ... Keep that in mind for future experiments :-)
When an object's destructor is called, it's undefined behavior to use it.
The C++ 1 standard specifies this (translation and highlighting mine).
The wording of the standard is very confusing, but it goes to say that when the life of an object has expired, that object should not be used and if you do use it, you don't know what might happen.
The sub-object
Persona::nombre
of typestd::string
is an object with a destructor. By calling the destructor ofPersona
, all the destructors of all its sub-objects are cascaded. One of the things the destructor doesstd::string
is remove the memory it uses. Instead, thePersona::edad
type sub-objectint
is a fundamental type and lacks a destructor, the space it occupies will be marked as " available " and can be called up by the operating system whenever it pleases. Its previous value is displayed precisely because no one has claimed that space.You don't have to confirm anything, when an object is destroyed you have to forget that it exists.