您的位置:首页 > 其它

virtual与析构函数引起我的悲剧

2013-02-02 09:13 141 查看
virtual与析构函数引起我的悲剧

场景: 定义一个接口类, 不同子类实现接口. 实现多态. 看下面代码

// virtual与析构函数引起我的悲剧
// File.h
class MyInterface
{
public:
virtual int Fun1() = 0;
virtual int Fun2() = 0;
virtual int Fun3() = 0;
};
///////////////////////////////////////////
class MySubClass : public MyInterface
{
public:
MySubClass();
virtual ~MySubClass();
virtual int Fun1();
virtual int Fun2();
virtual int Fun3();
private:
unsigned char* m_pData;
};
//////////////////////////////////////////////////////////////
// File.cpp
MySubClass::MySubClass()
{
m_pData = new char[20];
}

MySubClass::~MySubClass()
{
delete [] m_pData;
}

int MySubClass::Fun1()
{
return 1;
}
int MySubClass::Fun2()
{
return 2;
}

int MySubClass::Fun3()
{
return 3;
}
///////////////////////////////////////////////////////////////////////////////
// Use.cpp
#include "File.h"
MyInterface* pMyInterface = new MySubClass;
pMyInterface->Fun1();
delete pMyInterface;


悲剧发生: 内存泄露了! 这么就简单的一段代码, 内存泄露了? 该delete的我都delete

排查: 调试发现MySubClass的析构函数没有调用.

原因: delete pMyInterface; 调用的是MyInterface类的编译器给的析构函数(因为我在MyInterface定义中没有给出析构函数). 不是多态吗? 应该先调用MySubClass的析构函数吗?

 很明显, 编译器给的MyInterface的析构函数没有virtual修饰, 所以delete pMyInterface并没有多态.

更悲剧的事情: 如果我是在上面代码上发现这个问题, 找原因可能一下子就可以找到了, 可是不是啊, 是在另外一个工程中发生了内存泄露, 

找啊找啊找啊, 用了我两天的时间啊........ 鬼才知道是这个基础的原因引起, 

总结教训: 

排查原因要分主次

1. 先从最基础的原因入手, 从最常见的错误原因入手. 例如上面说的原因; 例如new了, 没delete;

2. 在确保了不是1引起的, 再去看程序的逻辑流程. 例如虽然new了也对应delete了, 但是由于一些跳转引起了并没有调用delete.

3. 在排查程序的逻辑流程的时候, 单元测试要做好. 通常程序有好几个或者几十个单元模块组成, 这么多个模块扯在一起, 是模块实现问题还是模块调用问题? 谁知道. 

    如果你确保了某个单元模块的实现是绝对没问题的, 可以迅速排出很多原因的.

正确代码是:

// virtual与析构函数引起我的悲剧
// File.h
class MyInterface
{
public:
MyInterface(){}
virtual MyInterface(){} // ----------------------就加多这两句-------------------------
virtual int Fun1() = 0;
virtual int Fun2() = 0;
virtual int Fun3() = 0;
};

class MySubClass : public MyInterface
{
public:
MySubClass();
virtual ~MySubClass();
virtual int Fun1();
virtual int Fun2();
virtual int Fun3();
private:
unsigned char* m_pData;
};

// File.cpp
MySubClass::MySubClass()
{
m_pData = new char[20];
}

MySubClass::~MySubClass()
{
delete [] m_pData;
}

int MySubClass::Fun1()
{
return 1;
}
int MySubClass::Fun2()
{
return 2;
}

int MySubClass::Fun3()
{
return 3;
}

// Use.cpp #include "File.h" MyInterface* pMyInterface = new MySubClass; pMyInterface->Fun1(); delete pMyInterface;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: