返回信息流在图一中,单例类中使用了嵌套类来析构单例对象,此时单例对象在程序结束运行时才会被析构;在图二中我在单例类中添加了析构函数~sigleC(),然后在main函数中delete p1,运行出现异常;在图三中我在main函数中delete p1处打了断点,然后逐语句调试,发现进入~sigleC()之后循环执行方框中的两行,不会执行m_instance = nullptr这一行,~sigleC()函数一直不能结束。
想问问大佬这是怎么回事[ema13],谢谢
这是一条镜像帖。来源:北邮人论坛 / cpp / #99844同步于 2020/4/16
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
c++单例模式中为什么不能在析构函数中直接delete对象?
gcl
2020/4/16镜像同步28 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
delete p1调用sigleC的析构,sigleC析构再delete instance,instance也是sigleC成员,重复调用sigleC的析构。以上,开始套娃
泻药 一楼和楼上说的对 delete 等价于 ~+free 如果你自己写过allocator就应该对这个知识点很熟悉了
另外部分不同意二楼 C++里的单例模式非常广泛 只是楼主的写法不对 其实很简单 坚持一个原则:怎么new出来就怎么delete掉
楼主这种写法get的时候发现是nullptr就new的写法很常见 但是楼主的free用法不对 这种情况不应该在析构free 而是应该再搞个static destroy函数 在main结束前delete掉
还有一种写法是干脆把instance搞成static member(或者不member也行),这种就省去自己析构了
但是其实static member和global static都有一个问题,就是不明确构造顺序(当然也就不明确析构顺序),如果有依赖其他static的东西就傻了,或者用__attribute__ ((init_priority(65535)))这种骚操作
不过我最常用的写法是这样
static Shit* get_instance() {
static Shit;
return &Shit;
}
这种写法的好处就是不调用的时候不构造,用完程序结束自己销毁,当然我不确定这样有没有并发问题(反正我从来没遇到过)
图二在类的析构函数中调用类的析构函数。导致一直重复调用析构函数,直到栈溢出,报错。
Debug方法:F11单步调试 + 打开VS的反汇编窗口(反汇编可以看到delete调用了析构函数)
另外,图二中的析构函数是没有意义的。main中已经使用了delete p1;再添加一句p1=nullptr;就回收了内存。
一般来说,构造函数和析构函数是一对的,析构函数应该处理构造函数中申请的资源。
这很明显了吧,你的p1和m_instance都是sigleC指针,你delete p1时调用析构函数,析构函数又delete m_instance,这时候敲黑板了,m_instance又会调用析构函数,而且只有在析构函数跑完才算delete完毕,所以再再次调用的析构函数里m_instance依然是有效指针,所以死亡循环开始