本帖最后由 baizy77 于 2018-10-12 11:40 编辑
版权声明--------------------------------------------------------------------------------------------------------------------- 作者: 女儿叫老白 (白振勇) 转载请注明出处! --------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------
引言: ---------------------------------------------------------------------------- 本文主要内容引自《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[m_nSzie];
- 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 Eckel Chuck Allison著
|