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]