C++ pure virtual function call

最近在写代码的时候,遇到“pure virtual function call”的报错:


问题的背景是这样的,Thread是一个线程的基类,Thread的代码如下:

#ifndef _THREAD_H_
#define _THREAD_H_

#include <Windows.h>
#include <process.h>

class Thread
{
public:
	Thread(): m_stopFlag(false), m_hThread(INVALID_HANDLE_VALUE){}
	virtual ~Thread(){Stop();}

	/// @brief		执行的主体
	/// @param[in]	void
	///	@remark		继承与Thread的类须实现Run函数
	///	@return		
	virtual void Run() = 0;

	/// @brief		启动线程
	///	@remark		
	///	@return		void
	void Start()
	{
		m_stopFlag = false;
		unsigned int *pData = NULL;
		m_hThread = (HANDLE)_beginthreadex(NULL, 0, thread_proc, this, 0, pData);
	}

	/// @brief		终止线程
	///	@remark		
	///	@return		void
	void Stop()
	{
		m_stopFlag = true;
		if(m_hThread != INVALID_HANDLE_VALUE)
		{
			if(WaitForSingleObject(m_hThread,INFINITE) != WAIT_ABANDONED)
			{
				CloseHandle(m_hThread);
			}
			m_hThread = INVALID_HANDLE_VALUE;
		}
	}

	/// @brief		判断线程是否停止
	///	@remark		
	///	@return		已停止则返回ture,否则返回false
	bool IsStop()
	{
		return m_stopFlag;
	}

protected:
	static unsigned __stdcall thread_proc(LPVOID p)
	{
		Thread *pThis = (Thread *)p;
		pThis->Run();

		CloseHandle( pThis->m_hThread );
		pThis->m_hThread = INVALID_HANDLE_VALUE;

		return 0;
	}
private:
	bool    m_stopFlag;
	HANDLE	m_hThread;
};

#endif//_THREAD_H_
threadClass是继承于Thread的一个子类,代码如下:

class threadClass : public Thread
{
public:
	virtual void Run()
	{
		for (int i=0; i<10; ++i)
		{
			printf("threadClass Run %d\n", i);
			::Sleep(1);
		}
	}
};
测试的代码如下:

int main()
{
	threadClass cls;
	cls.Start();
	//_sleep(1000);
	//cls.Stop();

	//system("pause");

	return 0;
}

        问题来了,如果直接执行程序,将直接报错pure virtual function call”。如果放开main()函数中注释掉的三行代码中的任意一行,程序都将正确执行(循环打印0~9在屏幕显示)。经过分析,可以找到问题所在:

        如果不执行_sleep(1000),程序(主线程)启动后就立即return 0了,而子线程还未退出,从而导致子线程在执行析构的时候抛出异常了!所以,必须等待子线程执行完毕(或者终止子线程),此时退出主线程,才可以保证程序正确执行!
-------------------------------------------------------------------------------------------------------------------

最近又遇到这样的问题,通过调试发现,是PostThreadMessage的时候,第一个参数传的线程id是一个无效的ID,直接通过GetCurrentThreadId获取当前线程ID,就没这个bug了!



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hellokandy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值