0

I created a class User and I instantiated an object me of that class, then I tried to delete that object using ~User(); destructor, but it didn't work, I still have the object and its data. here is my code:

#include <iostream>
#include <string>
using namespace std;
class User
{
    string gender="male";
    public:
        string first_name;
        string last_name;
        string get_gender()
        {return gender;}
        User(){};
        ~User(){};
};
int main()
{
    User me;
    me.first_name="Ali";
    me.last_name ="Said";
    cout<<"First Name: "<<me.first_name<<endl;
    cout<<"Last Name: "<<me.last_name<<endl;
    cout<<"Gender: "<<me.get_gender()<<endl;
    me.~User();
    cout<<me.first_name<<endl;
    return 0;
}
  • *" but it didn't work..."* What doesn't work mean? Do you get an error? Or something else. See [using an object after it's destructor is called](https://stackoverflow.com/questions/13067765/using-an-object-after-its-destructor-is-called) – Jason Oct 13 '22 at 06:59
  • 4
    You are not typically supposed to call destructors explicitly. `me` is a automatic storage duration variable. It will be destroyed (via a call to the destructor) automatically at the end of its scope. What you are doing here just ends in undefined behavior, for one because accessing a member after the destructor call is undefined and for two because the automatic destructor call at the end of the scope needs the object to be alive. – user17732522 Oct 13 '22 at 07:00
  • 2
    Since you didn't allocate anything in that `class` with `new` there's nothing here you need to delete. The desctructor should be empty. Tip: **DO NOT CALL DESTRUCTORS** as if they were functions. When that variable falls out of scope it will be destructed again, and that could be undefined behaviour and lead to a crash. – tadman Oct 13 '22 at 07:01
  • 2
    *"I still have the object and its data"* Using that is undefined behavior. *"Undefined behavior means anything can happen including but not limited to the program giving your expected output. But never rely on the output of a program that has UB. The program may just crash"*. – Jason Oct 13 '22 at 07:01
  • 1
    Tip: `const string& get_gender()` to avoid pointless copies. – tadman Oct 13 '22 at 07:03
  • 1
    `me.~User();` -- This is a case of accidentally coming across something in C++ that will compile, but can have disastrous results. It is also the case of not using good C++ books to learn from. A good C++ book would *never* show code like this, unless it is an advanced book talking about `placement-new`. – PaulMcKenzie Oct 13 '22 at 07:08
  • @tadman It ends the object lifetime, and accessing the members after that causes UB, and so does the automatic destructor at the end of scope. It only happens to work because of SSO. – HolyBlackCat Oct 13 '22 at 07:14
  • Pro tip: Don't define an empty destructor if you don't need it. It has a hidden effect of disabling move semantics for your class, unless you go out of your way to opt into them. – HolyBlackCat Oct 13 '22 at 07:15
  • @HolyBlackCat Does it release the memory on the stack? – tadman Oct 13 '22 at 07:16
  • @tadman No, it just ends the object lifetime, while leaving the memory allocated. It would release heap-allocated string contents, if they were long enough to not be SSOed. – HolyBlackCat Oct 13 '22 at 07:19
  • @HolyBlackCat I see what you mean now. Thanks for explaining. – tadman Oct 13 '22 at 07:20
  • @tadman C++ does not describe "the stack". An implementation that uses a stack for local variables is free re-use stack space for objects who's lifetimes don't overlap. Commonly, many local variables *aren't allocated* and are instead only present as registers in the CPU – Caleth Oct 13 '22 at 08:25

0 Answers0