Why does reassigning a smart pointer to itself cause destruction?

孤者浪人 提交于 2019-12-11 04:48:50

问题


TLDR

Why does the line t_ptr = std::unique_ptr<Test>(t_ptr.get()); cause the destructor to be called?

The line seems to just innocently assign t_ptr back to itself...

Further, why am I able to continue calling methods after the supposed destruction?

Example Code

class Test
{
    public:
        Test()
        {
            printf("Constructor called: %p\n", this);
            i = 0;
        };
        void print()
        {
            printf("%d\n", i++);
        };
        ~Test()
        {
            printf("Destructor called: %p\n", this);
        };
    private:
        int i;
};

int main(int argc, char** argv)
{
    std::unique_ptr<Test> t_ptr = std::unique_ptr<Test>(new Test());
    t_ptr->print();
    t_ptr->print();
    t_ptr->print();
    t_ptr = std::unique_ptr<Test>(t_ptr.get());
    t_ptr->print();
    t_ptr->print();
    t_ptr->print();
};

The output is

Constructor called: 0x55c9811a1e70
0
1
2
Destructor called: 0x55c9811a1e70
0
1
2
Destructor called: 0x55c9811a1e70

回答1:


Why does the line t_ptr = std::unique_ptr<Test>(t_ptr.get()); cause the destructor to be called?

Because unique_ptr needs to delete the currently held object when assigning it a new one. Otherwise it would leak the current object. However, it will not check whether the new one is actually the same as the current one. If you do that, the behavior is undefined.

Further, why am I able to continue calling methods after the supposed destruction?

Because this is undefined behavior. You are calling functions on an object that has been deleted. What happens when you do that is undefined. On your system it works, on mine it crashes.

(Off-topic side note)

I recommend getting into the habit of never using new if you can avoid it, and using std::make_unique (or std::make_shared for shared_ptr) instead:

auto t_ptr = std::make_unique<Test>();

There's benefits with exception safety in some cases when the constructor throws. Basically, as of 2019 at least, the current rule of thumb is "do not use new or delete."



来源:https://stackoverflow.com/questions/55627418/why-does-reassigning-a-smart-pointer-to-itself-cause-destruction

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!