在STL中,map是一种非常灵活的关联容器,在使用map时一定要正确定义_Kty及_Pr。
map在定义如下:
template<class _Kty, class _Ty, class _Pr = less<_Kty>, class _Alloc = allocator<pair<const _Kty, _Ty> > >
class map
要实例化一个map首先要确定_Kty与_Ty的类型,其中_Kty为map的键值类型,_Ty为map的数据区的数据类型,_Pr为map比较键值的函数类(默认使用操作符“<”),而_Alloc 为map的配置器(默认使用系统配置器)。在一般情况下,我们只需要确定_Kty与_Ty就可实例化一个map对象。
当实例一个map容器std::map<key,ty> simMap;时,要保存key的操作符“<”可以正常工作,并且保证key类型的数据具有顺序性。
如下是一个错误的定义:
class
CMapRetryData
{
public :
// 键类型
typedef struct _tagMapItem
{
unsigned long m_ulTick;
unsigned char m_ucRetryCount;
std::auto_ptr < const SENDDATA > m_pSendData;
public :
_tagMapItem()
{
m_ulTick = ::GetTickCount();
m_ucRetryCount = 0 ;
// m_pSendData = NULL;
}
_tagMapItem( const _tagMapItem & v_source )
{
m_ulTick = v_source.m_ulTick;
m_ucRetryCount = v_source.m_ucRetryCount;
const SENDDATA * pSour;
SENDDATA * pDest;
m_pSendData = std::auto_ptr < const SENDDATA > ( new SENDDATA);
pSour = v_source.m_pSendData. get ();
if ( NULL != pSour )
{
pDest = const_cast < SENDDATA *> (m_pSendData. get ());
::memcpy( pDest, pSour, sizeof (SENDDATA) );
}
else
{
m_pSendData.reset();
}
}
~ _tagMapItem()
{
m_pSendData.reset();
}
} CMapItem;
// 内容类型
typedef struct _tagMapKey
{
unsigned long m_ulTerminaID;
unsigned char m_ucBussType;
unsigned char m_ucDataType;
public :
_tagMapKey()
{
m_ulTerminaID = 0 ;
m_ucBussType = 0 ;
m_ucDataType = 0 ;
}
_tagMapKey( const _tagMapKey & v_source )
{
m_ulTerminaID = v_source.m_ulTerminaID;
m_ucBussType = v_source.m_ucBussType;
m_ucDataType = v_source.m_ucDataType;
}
~ _tagMapKey()
{
}
bool operator == ( const _tagMapKey & v_source ) const
{
return ((m_ulTerminaID == v_source.m_ulTerminaID) &&
(m_ucBussType == v_source.m_ucBussType) &&
(m_ucDataType == v_source.m_ucDataType));
}
bool operator < ( const _tagMapKey & v_source ) const
{
{
public :
// 键类型
typedef struct _tagMapItem
{
unsigned long m_ulTick;
unsigned char m_ucRetryCount;
std::auto_ptr < const SENDDATA > m_pSendData;
public :
_tagMapItem()
{
m_ulTick = ::GetTickCount();
m_ucRetryCount = 0 ;
// m_pSendData = NULL;
}
_tagMapItem( const _tagMapItem & v_source )
{
m_ulTick = v_source.m_ulTick;
m_ucRetryCount = v_source.m_ucRetryCount;
const SENDDATA * pSour;
SENDDATA * pDest;
m_pSendData = std::auto_ptr < const SENDDATA > ( new SENDDATA);
pSour = v_source.m_pSendData. get ();
if ( NULL != pSour )
{
pDest = const_cast < SENDDATA *> (m_pSendData. get ());
::memcpy( pDest, pSour, sizeof (SENDDATA) );
}
else
{
m_pSendData.reset();
}
}
~ _tagMapItem()
{
m_pSendData.reset();
}
} CMapItem;
// 内容类型
typedef struct _tagMapKey
{
unsigned long m_ulTerminaID;
unsigned char m_ucBussType;
unsigned char m_ucDataType;
public :
_tagMapKey()
{
m_ulTerminaID = 0 ;
m_ucBussType = 0 ;
m_ucDataType = 0 ;
}
_tagMapKey( const _tagMapKey & v_source )
{
m_ulTerminaID = v_source.m_ulTerminaID;
m_ucBussType = v_source.m_ucBussType;
m_ucDataType = v_source.m_ucDataType;
}
~ _tagMapKey()
{
}
bool operator == ( const _tagMapKey & v_source ) const
{
return ((m_ulTerminaID == v_source.m_ulTerminaID) &&
(m_ucBussType == v_source.m_ucBussType) &&
(m_ucDataType == v_source.m_ucDataType));
}
bool operator < ( const _tagMapKey & v_source ) const
{
// 这里是问题所在
return ((m_ulTerminaID < v_source.m_ulTerminaID) &&
(m_ucBussType < v_source.m_ucBussType) &&
(m_ucDataType < v_source.m_ucDataType));
}
bool operator != ( const _tagMapKey & v_source ) const
{
return ((m_ulTerminaID != v_source.m_ulTerminaID) ||
(m_ucBussType != v_source.m_ucBussType) ||
(m_ucDataType != v_source.m_ucDataType));
}
} CMapKey;
// 比较类
class CCompare
{
public :
bool operator () ( const CMapKey & v_key1, const CMapKey & v_key2 ) const
{
return ((m_ulTerminaID < v_source.m_ulTerminaID) &&
(m_ucBussType < v_source.m_ucBussType) &&
(m_ucDataType < v_source.m_ucDataType));
}
bool operator != ( const _tagMapKey & v_source ) const
{
return ((m_ulTerminaID != v_source.m_ulTerminaID) ||
(m_ucBussType != v_source.m_ucBussType) ||
(m_ucDataType != v_source.m_ucDataType));
}
} CMapKey;
// 比较类
class CCompare
{
public :
bool operator () ( const CMapKey & v_key1, const CMapKey & v_key2 ) const
{
// 这里是问题所在
return ((v_key1.m_ulTerminaID >= v_key2.m_ulTerminaID) &&
(v_key1.m_ucBussType >= v_key2.m_ucBussType) &&
(v_key1.m_ucDataType >= v_key2.m_ucDataType));
}
};
typedef std::map < CMapKey, CMapItem /* , CCompare */ > CDataMap;
public :
CMapRetryData()
// : m_dataMap()
{
}
~ CMapRetryData()
{
m_dataMap.clear();
}
private :
// Map类
CDataMap m_dataMap;
public :
CMapItem & operator [] ( const CMapKey & v_key )
{
return m_dataMap[v_key];
}
void DeleteItem( CMapKey & v_key )
{
m_dataMap.erase(v_key);
}
const SENDDATA * FindOverTime();
};
return ((v_key1.m_ulTerminaID >= v_key2.m_ulTerminaID) &&
(v_key1.m_ucBussType >= v_key2.m_ucBussType) &&
(v_key1.m_ucDataType >= v_key2.m_ucDataType));
}
};
typedef std::map < CMapKey, CMapItem /* , CCompare */ > CDataMap;
public :
CMapRetryData()
// : m_dataMap()
{
}
~ CMapRetryData()
{
m_dataMap.clear();
}
private :
// Map类
CDataMap m_dataMap;
public :
CMapItem & operator [] ( const CMapKey & v_key )
{
return m_dataMap[v_key];
}
void DeleteItem( CMapKey & v_key )
{
m_dataMap.erase(v_key);
}
const SENDDATA * FindOverTime();
};
这段代码是一个map的应用,这里map的键值类重载了操作符“<”,也实现了一个比较类CCompare。这里出现的问题j是操作符重符后的键值类型不具有顺序性,例:
CMapRetryData::CMapKey key1, key2;
key1.m_ulTerminaID = 1 ;
key1.m_ucBussType = 0x19 ;
key1.m_ucDataType = 0x01 ;
key2.m_ulTerminaID = 1 ;
key2.m_ucBussType = 0x19 ;
key2.m_ucDataType = 0x02 ;
// 有如下表达式成立
( key1 < key2 ) == false ;
( key2 < key1 ) == false ;
key1.m_ulTerminaID = 1 ;
key1.m_ucBussType = 0x19 ;
key1.m_ucDataType = 0x01 ;
key2.m_ulTerminaID = 1 ;
key2.m_ucBussType = 0x19 ;
key2.m_ucDataType = 0x02 ;
// 有如下表达式成立
( key1 < key2 ) == false ;
( key2 < key1 ) == false ;
上述代码说明CMapKey类型没有顺序性,这产生的后果就是不能通过已知的键值查找键值对应的数据内容。
因此,将出错部分进行如下修改:
//
键类型
typedef struct _tagMapKey
{
unsigned long m_ulTerminaID;
unsigned char m_ucBussType;
unsigned char m_ucDataType;
public :
_tagMapKey()
{
m_ulTerminaID = 0 ;
m_ucBussType = 0 ;
m_ucDataType = 0 ;
}
_tagMapKey( const _tagMapKey & v_source )
{
m_ulTerminaID = v_source.m_ulTerminaID;
m_ucBussType = v_source.m_ucBussType;
m_ucDataType = v_source.m_ucDataType;
}
~ _tagMapKey()
{
}
bool operator == ( const _tagMapKey & v_source ) const
{
return ((m_ulTerminaID == v_source.m_ulTerminaID) &&
(m_ucBussType == v_source.m_ucBussType) &&
(m_ucDataType == v_source.m_ucDataType));
}
bool operator < ( const _tagMapKey & v_source ) const
{
return (m_ulTerminaID != v_source.m_ulTerminaID ? m_ulTerminaID < v_source.m_ulTerminaID :
(m_ucBussType != v_source.m_ucBussType ? m_ucBussType < v_source.m_ucBussType :
(m_ucDataType < v_source.m_ucDataType)));
// return ((m_ulTerminaID < v_source.m_ulTerminaID) &&
// (m_ucBussType < v_source.m_ucBussType) &&
// (m_ucDataType < v_source.m_ucDataType));
}
bool operator != ( const _tagMapKey & v_source ) const
{
return ((m_ulTerminaID != v_source.m_ulTerminaID) ||
(m_ucBussType != v_source.m_ucBussType) ||
(m_ucDataType != v_source.m_ucDataType));
}
} CMapKey;
// 比较类
class CCompare
{
public :
bool operator () ( const CMapKey & v_key1, const CMapKey & v_key2 ) const
{
return (v_key1.m_ulTerminaID != v_key2.m_ulTerminaID ? v_key1.m_ulTerminaID < v_key2.m_ulTerminaID :
(v_key1.m_ucBussType != v_key2.m_ucBussType ? v_key1.m_ucBussType < v_key2.m_ucBussType :
(v_key1.m_ucDataType < v_key2.m_ucDataType)));
// return ((v_key1.m_ulTerminaID >= v_key2.m_ulTerminaID) &&
// (v_key1.m_ucBussType >= v_key2.m_ucBussType) &&
// (v_key1.m_ucDataType >= v_key2.m_ucDataType));
}
};
typedef struct _tagMapKey
{
unsigned long m_ulTerminaID;
unsigned char m_ucBussType;
unsigned char m_ucDataType;
public :
_tagMapKey()
{
m_ulTerminaID = 0 ;
m_ucBussType = 0 ;
m_ucDataType = 0 ;
}
_tagMapKey( const _tagMapKey & v_source )
{
m_ulTerminaID = v_source.m_ulTerminaID;
m_ucBussType = v_source.m_ucBussType;
m_ucDataType = v_source.m_ucDataType;
}
~ _tagMapKey()
{
}
bool operator == ( const _tagMapKey & v_source ) const
{
return ((m_ulTerminaID == v_source.m_ulTerminaID) &&
(m_ucBussType == v_source.m_ucBussType) &&
(m_ucDataType == v_source.m_ucDataType));
}
bool operator < ( const _tagMapKey & v_source ) const
{
return (m_ulTerminaID != v_source.m_ulTerminaID ? m_ulTerminaID < v_source.m_ulTerminaID :
(m_ucBussType != v_source.m_ucBussType ? m_ucBussType < v_source.m_ucBussType :
(m_ucDataType < v_source.m_ucDataType)));
// return ((m_ulTerminaID < v_source.m_ulTerminaID) &&
// (m_ucBussType < v_source.m_ucBussType) &&
// (m_ucDataType < v_source.m_ucDataType));
}
bool operator != ( const _tagMapKey & v_source ) const
{
return ((m_ulTerminaID != v_source.m_ulTerminaID) ||
(m_ucBussType != v_source.m_ucBussType) ||
(m_ucDataType != v_source.m_ucDataType));
}
} CMapKey;
// 比较类
class CCompare
{
public :
bool operator () ( const CMapKey & v_key1, const CMapKey & v_key2 ) const
{
return (v_key1.m_ulTerminaID != v_key2.m_ulTerminaID ? v_key1.m_ulTerminaID < v_key2.m_ulTerminaID :
(v_key1.m_ucBussType != v_key2.m_ucBussType ? v_key1.m_ucBussType < v_key2.m_ucBussType :
(v_key1.m_ucDataType < v_key2.m_ucDataType)));
// return ((v_key1.m_ulTerminaID >= v_key2.m_ulTerminaID) &&
// (v_key1.m_ucBussType >= v_key2.m_ucBussType) &&
// (v_key1.m_ucDataType >= v_key2.m_ucDataType));
}
};