C++:对象已删除(使用new创建)但成员函数仍在工作(?)

rsp*_*rsp 0 c++ oop g++

只是为了好奇和实验,我写了下面的代码,现在我想了解删除后发生的事情...为什么猫对象还在喵喵?

我使用的编译器版本:

g++ (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609
Run Code Online (Sandbox Code Playgroud)

并编译代码:

g++ cat.cpp -pedantic -Wall -o cat
Run Code Online (Sandbox Code Playgroud)

在删除后调用meou()时,其他编译器可能会崩溃.

我想知道

  • 为什么不崩溃
  • 我应该采取哪些预防措施

代码:

#include <iostream>
using namespace std;


class Cat
{
    public:
        Cat()  { cout << "Cat construct" << endl; }
        ~Cat() { cout << "Cat destruct" << endl; }
        void meow(); 
};

void Cat::meow(void)
{
    cout << "meow..." << endl;
}    

int main()
{
    Cat * pCat = new Cat;    
    pCat->meow();    
    cout << "pCat = " << pCat << endl;    
    delete pCat;    
    pCat = NULL;    
    cout << "pCat = " << pCat << endl;    
    pCat->meow();    
    cout << "why still meowing?!" << endl;    
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

Cat construct
meow...
pCat = 0x2147030
Cat destruct
pCat = 0
meow...
why still meowing?!
Run Code Online (Sandbox Code Playgroud)

Chr*_*ckl 6

为什么不崩溃

因为取消引用nullptr或访问已删除的对象是未定义的行为.C++没有必需的崩溃,但崩溃可能是未定义行为的结果.

我应该采取哪些预防措施

这是一个相当广泛的话题.如果你不需要,C++中最重要的事情就是不使用动态分配.写:

Cat cat;
cat.meow();
Run Code Online (Sandbox Code Playgroud)

如果你不能那样做,请使用std::unique_ptr:

auto cat_ptr = std::make_unique<Cat>();
cat_ptr->meow();
Run Code Online (Sandbox Code Playgroud)

如果您需要集合,请不要使用new[].用途std::vector:

std::vector<Cat> cats;
std::vector<std::unique_ptr<Cat>> cat_ptrs;
Run Code Online (Sandbox Code Playgroud)