1.char* p = "123abc";
if( p == "123abc" ) 和
std::string str = "123abc";
if( str == "123abc" )
是可以的,用char []是不行的,== 比较的是地址
2.
class CT
{
public:
CT(int v)
{
m_v = v;
}
public:
int m_v;
char buf[0]; //必须在最后,否则出错
public:
/*默认new的原型是:void* operator new(size_t size)
*把类的最后一个成员变量定义为char buf[0],然后如下
*重载new操作符,为一个类指针分配一个堆空间,把类
*当普通指针使用,很特别!
*/
void* operator new(size_t objsize, size_t bufsize)
{
void* pMem = new char[objsize + bufsize];
return pMem;
}
void operator delete(void *p)
{
delete [] p;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
CT *p = new(10) CT(13); //10,即是operator new() bufsize参数
return 0;
}
3.
std::string 类似于CString::GetBuffer/ReleaseBuffer的用法
std::string str = "aaa";
char* p = (char*)&str[0];
strcpy(p, "bbb");
4.
GetSystemTime()获取的是格林威治(UTC)时间,小时要加8
5.关于CCriticalSection的实现
class CCritSecLock
{
public:
CCritSecLock( CRITICAL_SECTION& cs, bool bInitialLock = true );
~CCritSecLock() throw();
void Lock();
void Unlock() throw();
// Implementation
private:
CRITICAL_SECTION& m_cs;
bool m_bLocked;
// Private to avoid accidental use
CCritSecLock( const CCritSecLock& ) throw();
CCritSecLock& operator=( const CCritSecLock& ) throw();
};
inline CCritSecLock::CCritSecLock( CRITICAL_SECTION& cs, bool bInitialLock ) :
m_cs( cs ),
m_bLocked( false )
{
if( bInitialLock )
{
Lock();
}
}
inline CCritSecLock::~CCritSecLock() throw()
{
if( m_bLocked )
{
Unlock();
}
}
inline void CCritSecLock::Lock()
{
ATLASSERT( !m_bLocked );
__try
{
::EnterCriticalSection( &m_cs );
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
AtlThrow( E_OUTOFMEMORY );
}
m_bLocked = true;
}
inline void CCritSecLock::Unlock() throw()
{
ATLASSERT( m_bLocked );
::LeaveCriticalSection( &m_cs );
m_bLocked = false;
}
这是MFC的实现,显然在使用该类之前,m_cs必须被初始化过
6.TryEnterCriticalSection
class QMutex {
private:
CRITICAL_SECTION m_Cs;
public:
QMutex() { ::InitializeCriticalSection(&this->m_Cs); } //注意:这里并没有把Lock()/UnLock写进构造函数和析构函数
~QMutex() { ::DeleteCriticalSection(&this->m_Cs); }
void Lock() { ::EnterCriticalSection(&this->m_Cs); }
BOOL TryLock() { return (BOOL) ::TryEnterCriticalSection(&this->m_Cs); }
void Unlock() { ::LeaveCriticalSection(&this->m_Cs); }
};
EnterCriticalSection:一直等待直到获取到权限为止
TryEnterCriticalSection:无论成功与否都会立马返回
用法:
if( m_QMutex.TryLock() )
{}
m_QMutext.Lock();
7.这样定义一个类,就可以限制run()只能被某些特定类使用,而不能被直接使用
class IRunnable {
friend class CThread;
friend class CSimpleThreadPool;
protected:
virtual void run() = 0;
};
8.
class CThread: public IRunnable {
private:
static TLSDescriptor m_TLSDesc;
volatile bool m_bIsInterrupted;
volatile bool m_bIsRunning;
}
使用volatie是为了在线程执行的过程中可以被及时告知应当终止
9.应熟悉这种间接调用线程函数的方法,使得线程函数可以被适配。
class CThread : public IRunnable{
static DWORD WINAPI StartThreadST(LPVOID PARAM) {
CThread* _this = (CThread*)PARAM;
if( _this != NULL )
{
_this->m_QMutext.Lock();
...
_this->run();
...
_this->m_QMutext.UnLock();
}
}
~ CThread()
{
join();
}
void join()
{ //因为在线程函数执行的前后也要获取m_QMutext,所以这里只有在线程函数执行完毕后才会获取到权限
//这种等待线程执行完毕的方法以前没见过
m_QMutext.Lock();
m_QMutext.UnLock();
}
};
10.
class CPriority
{
public:
CPriority(int m):m_pri(m){}
public:
GetPriority()
{
return m_pri;
}
private:
int m_pri;
};
//这样直接写在外面,虽然知道,但没这么做过,乍看之下感觉有点陌生。。日。。
bool operator < ( CPriority & p1, CPriority & p2 )
{
return ( p1.GetPriority() < p2.GetPriority() );
}
11.适用IOCP的SOCKET必须
nSock = WSASocket(..., ..., ..., ..., ..., WSA_FLAG_OVERLAPPED);
12.WSAAccept()是同步的,只是添加一个允许客户端连接的条件
listen()的参数表示一次可以同时接受的连接数
accept:
If an error occurs, INVALID_SOCKET is returned. The most common error encountered isWSAEWOULDBLOCK if the listening socket is in asynchronous or non-blocking mode and there is no connection to be accepted
A graceful close is associated with connection-oriented protocols only