记一次虚函数使用的查错过程

起因

一个基础库中对资源回收的行为出现异常,经过排查,发现是基础库实现时对虚函数的调用出现问题造成的,记录下来吧。

纯虚函数的版本

#include <iostream>
using namespace std;

class B
{
	public:
		~B()
		{
			close();
		}

		void close()
		{
			doClose();
		}

		virtual void doClose() = 0;
};

class D : public B
{
	virtual void doClose()
	{
		cout <<"D::doClose()" <<endl;
	}
};

int main(int argc, char *argv[])
{
	B * p = new D();
	p->close();
	delete p;

	return 0;
}

# g++ main.cpp && ./a.out 
D::doClose()
pure virtual method called
terminate called without an active exception
Aborted

这里很好理解,D先于B析构,之后的doClose就没有对应的函数可用。

普通虚函数版本

#include <iostream>
using namespace std;

class B
{
	public:
		~B()
		{
			close();
		}

		void close()
		{
			doClose();
		}

		virtual void doClose()
		{
			cout <<"B::doClose()" <<endl;
		}
};

class D : public B
{
	virtual void doClose()
	{
		cout <<"D::doClose()" <<endl;
	}
};

int main(int argc, char *argv[])
{
	B * p = new D();
	p->close();
	delete p;

	return 0;
}

# g++ main.cpp && ./a.out 
D::doClose()
B::doClose()

道理也很好理解,D析构后,B析构时调用的doClose指向B::doClose的实现,出现问题的代码逻辑就是这种实现。

总结

库中这块代码逻辑的原意是希望在对象析构时释放占用的资源,当释放资源的操作是纯虚函数时,程序异常退出,问题提前出现。而当释放资源的操作是普通虚函数时,问题就被隐藏掉了,如果管理的资源不是非常敏感的资源,问题可能就会被带到上线后再出现,而且排错非常麻烦。
一切的一切还是要看基本功啊

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值