baizy77 发表于 2018-10-12 09:01:02

C++老鸟日记039 关于delete的丁点常识

本帖最后由 baizy77 于 2018-10-12 11:40 编辑

版权声明---------------------------------------------------------------------------------------------------------------------该文章原创于Qter开源社区(www.qter.org)作者: 女儿叫老白 (白振勇)转载请注明出处!---------------------------------------------------------------------------------------------------------------------课程目录:《C++老鸟日记》目录本套课程属于:《C++跨平台开发干货》系列课程。---------------------------------------------------------------------------------------------------------------------

引言:----------------------------------------------------------------------------       本文主要内容引自《C++编程思想》(注1)。       今天我们介绍一点delete的知识,虽然比较简单,但还是需要引起大家的注意。
正文:----------------------------------------------------------------------------       首先介绍一个常识,在使用指针时,如果指针被赋值指向一块new出的内存,当使用完毕后,我们会将指针delete,delete之后请将指针赋值为NULL。这是防止将一个对象删除两次的一个有效方法,比如:代码清单:----------------------------------------------------------------------------
// func.cpp
void CPlayWorld::func(void) {
m_pMyClassObject = new CMyClass();
       ……
       if (NULL != m_pMyClassObject) {
         delete m_pMyClassObject;
         m_pMyClassObject = NULL;
      }
      ……
----------------------------------------------------------------------------
       有时候,我们在编程时会用到void*指针,那么对void*指针进行delete操作是安全的吗?代码清单:----------------------------------------------------------------------------
// myclass.h
class CMyClass {
public:
    CMyClass(int size);
    ~CMyClass();

private:
    int m_nSize;
    void* m_pData;
};

// myclass.cpp
#include <iostream>
using std::cout;
using std::endl;

CMyClass::CMyClass(int size):m_nSize(size) {
    if (m_nSize>0) {
      m_pData = new char;
      cout << “正在构造…” << endl;
    }
}

CMyClass::~CMyClass(){
    if (NULL != m_pData) {
      delete[] m_pData;
      m_pData = NULL;
    }

    cout << “正在析构…”<<endl;
}

// main.cpp
int main(int argc, char* argv[]) {
    CMyClass* pObj = new CMyClass(20);
    if (NULL != pObj) {
      delete pObj;
      pObj = NULL;
    }

    void* pVoidObj = new CMyClass(20);
    if (NULL != pVoidObj) {
      delete pVoidObj;
      pVoidObj = NULL;
    }
}
----------------------------------------------------------------------------
       类CMyClass含有一个void*指针m_pData, 在构造函数中它被赋值指向一块“元”数据区,在析构函数中delete[] m_pData可以把内存释放,因为m_pData并没有指向对象,而仅仅指向一块原生数据块。       但在main()函数中,情况就不同了,我们看到使delete知道它所操作的类型是十分必要的。上述代码的输出信息如下:       正在构造…       正在析构…       正在构造…       当delete pObj时,编译器知道pObj是指向CMyClass类型对象的指针,所以它会调用对象的析构函数,所有内存都会正确释放;而delete pVoidObj时,编译器知道的是在delete一个void*指针,它并不知道pVoidObj指向对象的确切类型,所以它仅仅把pVoidObj对象的内存释放,而不会调用pVoidObj所指向对象的析构函数,这样就造成了内存泄漏。最后是一个老生常谈的问题,就是要根据对象的个数确定到底使用delete 还是delete[]。即使是编程老手有时也难免疏忽,因此请大家一定要重视。
结语:----------------------------------------------------------------------------       本文的内容介绍了delete的一点知识,主要内容引自《C++编程思想》两卷合订本。编写本文的目的主要是小编认为这些还是比较重要的,希望引起大家对语法细节的注意。
参考资料----------------------------------------------------------------------------注1:《C++编程思想》两卷合订本中文版(第13章),(美) Bruce EckelChuck Allison著

页: [1]
查看完整版本: C++老鸟日记039 关于delete的丁点常识