This question already has answers here: What will happen when I call a member function on a NULL object pointer? (6个答案) 5年前关闭。 我对此代码有疑问>任何讨论对于理解这些内容都将非常有帮助:class Singleton{private: static Singleton *single; Singleton() {} ~Singleton() {}public: static Singleton* getInstance() { if (!single) single = new Singleton(); return single; } void method() { cout << "Method of the singleton class" << endl; } static void destroy() { delete single; single = NULL; }};Singleton* Singleton::single = NULL;int main(){ Singleton *sc2; sc2 = Singleton::getInstance(); // sc2 is pointing to some memory location { Singleton *sc1 = Singleton::getInstance(); // sc1 and sc2 pointing to same memory location sc1->method(); Singleton::destroy(); // memory location deleted. cout << sc1; } sc2->method(); // ??? how this is working fine?? return 0;}在此块中,我们将删除“ Singleton :: destroy()”中的内存;{Singleton *sc1 = Singleton::getInstance(); sc1->method();Singleton::destroy();cout << sc1;}然后如何调用“ sc2-> method();”成功了吗?德瓦什 最佳答案 为什么运作?因为您要调用的函数是静态定义的,所以不需要this指针来调用它,并且函数本身不使用this指针。因此,该功能不会崩溃。但是,正如您提到的,该类正在被滥用。仍然允许使用destroy()函数的一种更安全的方法是对Singleton指针使用shared_ptr ()。这样,销毁变为:single.reset();如果其他任何人仍然有一个指针,它仍然有效。仅当您再次调用getInstance()时问题才会出现。到那时,您的“单人”有两个版本。尽管您有解决此问题的另一种可能的方法:一旦销毁被调用,您可以阻止对getInstance()的任何调用。getInstance() ... if(destroyed) throw std::runtime_error("singleton destroyed"); ...destroy() ... destroyed = true; ...更新资料按照g ++ / objdump -d(在Linux下,尽管它也可以在cygwin中工作)有一个用于调用方法的程序集副本:400978: 48 8b 45 f0 mov -0x10(%rbp),%rax40097c: 48 89 c7 mov %rax,%rdi40097f: e8 ae 00 00 00 callq 400a32 <_ZN9Singleton6methodEv>(P.S. objdump使用与通常的INTEL语法相反的寄存器反汇编。)如我们所见,编译器使用“ callq”。 this指针位于%rax中。 “ callq”不使用%rax。就汇编代码而言,该函数当前是静态的。在method()中,不使用%rax,因此无论其值如何都无关紧要:0000000000400a32 <_ZN9Singleton6methodEv>:400a32: 55 push %rbp400a33: 48 89 e5 mov %rsp,%rbp400a36: 48 83 ec 10 sub $0x10,%rsp400a3a: 48 89 7d f8 mov %rdi,-0x8(%rbp)400a3e: be 44 0b 40 00 mov $0x400b44,%esi400a43: bf 80 10 60 00 mov $0x601080,%edi400a48: e8 b3 fd ff ff callq 400800 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@plt>400a4d: be 30 08 40 00 mov $0x400830,%esi400a52: 48 89 c7 mov %rax,%rdi400a55: e8 c6 fd ff ff callq 400820 <_ZNSolsEPFRSoS_E@plt>400a5a: c9 leaveq400a5b: c3 retq