Здравствуйте!
Дали такую задачку: дана несложная программа на С++, которая демонстрирует асинхронный вызов функции. Необходимо в ней найти ошибку.
Код:
#include <windows.h>
#include <iostream>
#include <sstream>
#include <process.h>
namespace TST
{
class Exception
{
public:
Exception(const wchar_t* szwText)
: m_wstrText(szwText)
{;};
std::wstring What() const throw()
{
return m_wstrText;
};
protected:
const std::wstring m_wstrText;
};
void le_chk(BOOL bResult, const char* file, int line)
{
if(!bResult)
{
std::clog << "An error " << GetLastError() << "occured";
std::wostringstream os;
os << L"Win32 error occured: GetLastError returned " << GetLastError()
<< " in " << file << L"@" << line;
throw Exception(os.str().c_str());
};
};
#define TST_LE_CHECK(res) le_chk((res), __FILE__, __LINE__)
class CallBase
{
public:
virtual void Call() = 0;
};
class AsyncActionBase
{
public:
AsyncActionBase(CallBase* pCall)
: m_hThread(NULL)
{
unsigned uId = 0;
m_hThread = (HANDLE)_beginthreadex(
NULL, 0, &AsyncActionBase::thread_proc,
(void*)pCall, 0, &uId);
TST_LE_CHECK(!!m_hThread); // зачем двойное отрицание?
};
virtual ~AsyncActionBase()
{
if(m_hThread)
{
TST_LE_CHECK(WaitForSingleObject(m_hThread, INFINITE)
!= WAIT_FAILED);
TST_LE_CHECK(CloseHandle(m_hThread));
m_hThread = NULL;
};
};
protected:
static unsigned __stdcall thread_proc(void * p)
{
try
{
((CallBase*)p)->Call();
}
catch (const TST::Exception& excpt)
{
std::wcerr << excpt.What();
};
return 0;
};
HANDLE m_hThread;
};
class MyAsyncAction1
: public CallBase
, public AsyncActionBase
{
public:
MyAsyncAction1()
: AsyncActionBase(this) // передавать this в списке инициализации конструктору базового класса небезопасно,
{ // т.к. конструктор базового класса может воспользоваться еще неинициализированными
// членами производного класса
};
virtual ~MyAsyncAction1()
{
};
//CallBase
virtual void Call()
{
for(size_t i = 0; i < 100; ++i)
{
std::cout << "Test #" << (i+1) << std::endl;
Sleep(10);
};
};
};
};
int main()
{
try
{
TST::MyAsyncAction1 oBj;
}
catch (const TST::Exception& excpt)
{
std::wcerr << excpt.What();
};
};
Синтаксических ошибок нет. Прочесал весь код, но и логических ошибок не нашел. Запускается и завершается нить корректно, сигнатура функции Call верная, механизм обработки исключений тоже правильный..
Вообщем, я пришел к выводу, что ошибок здесь нет, разве что одна потенциальная ошибка и двойное отрицание (я отметил комментариями)
Ваше мнение?
Заранее спасибо!