龙仪的家

导航

<2006年5月>
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910

随笔分类

文章分类

收藏夹

随笔档案

文章档案

统计

我的常用网址

代码库之十二-GUID类(0.1)

感谢大家的支持(对我的批评也是支持!!毕竟我还没达到很高的层次)
to:清风雨
请恕我愚钝,没看懂你要表达的意思
operator int( void ) const 这么做的目的是什么?
to:周星星,Diviner
感谢你们提供新的方法,其实我对stl不熟悉,也几乎没什么时间去研究,只是使用而已.
to:hpho
感谢提供另一个方法,虽然我没试过,但我想应该没问题吧
你得建议还真的不错,当时我写的时候没考虑那么多
class __LGLIB__ lg_GUID:pulbic GUID 已加
this==&id已加
friend ostream& operator<<(ostream &os,const lg_GUID &id);已加
重载为友员方式?左操作数是该类类型的对象时才会考虑使用作为类成员的重载操作符,我这个左操作类必须是这个类的对象,所以好像没有必要吧。

现在这个帖子的名应该改为:如何在MAP中使用GUID了,呵呵,等有时间我整理一下:)
起源:

前一阵子要用map,可是map竟然不能直接用GUID ,例如 typedef map<GUID,classname *> MyMap这样竟然编译出错,我郁闷啊,又找不到原因,一怒之下就写了这个GUID类,一个对象要让map使用有一些条件的,比如要重载些操作符等等,这个类也是经过坛子里的人指点,包括阿荣等,这里表示感谢。

////////////////////////////////////////////////H///////////////////////////////////////////////////////////////

#ifndef LGLIB_GUID_H
#define LGLIB_GUID_H
#include <iostream>
using namespace std;
namespace lglib
{
 #ifndef GUIDMODE
  #define GUIDMODE
 #endif
 
 //COM 环境初始化
 class __LGLIB__ lg_ComEnv
 {
 public:
  lg_ComEnv(){::CoInitialize(NULL);}
  ~lg_ComEnv(){::CoUninitialize();}
 };
 
 //定义这个类的原因:原来在map中直接使用GUID总是报错
 //所以自己定义了一个GUID类,在类中重载了一些操作符
 //GUID定义

#define GUID_64(x,y,z) \
 ( ( ( uint64 ) x << 32 ) | ( ( uint64 ) ( y << 16 ) | ( uint64 ) z ) )
 
 class __LGLIB__ lg_GUID : public GUID
 {
 public:
  lg_GUID();
  lg_GUID(const GUID& id);
  lg_GUID(const lg_GUID& id);
  ~lg_GUID();
  void Change();
  
   inline bool operator<(const lg_GUID& id) const
  {
   uint64 left = GUID_64(Data1,Data2,Data3);
   uint64 right = GUID_64(id.Data1,id.Data2,id.Data3);
   
   if(left < right)
    return true;
   return false;
  }
  inline void operator=(const lg_GUID& id)
  {
   Data1 = id.Data1;
   Data2 = id.Data2;
   Data3 = id.Data3;
   memcpy(Data4,id.Data4,sizeof(Data4));
  }
  inline void operator=(const GUID& id)
  {
   Data1 = id.Data1;
   Data2 = id.Data2;
   Data3 = id.Data3;
   memcpy(Data4,id.Data4,sizeof(Data4));
  }
  inline bool operator==(const GUID& id) const
  {
   if(Data1 == id.Data1&& Data2 == id.Data2&&
    Data3 == id.Data3&&memcmp(Data4,id.Data4,sizeof(Data4)) ==0 )
    return true;
   return false;
  }
  void print(OutputType type = Output_Console);
  
  inline bool operator==(const lg_GUID& id) const
  {
   if(this == &id)
    return true;
   if(Data1 == id.Data1&& Data2 == id.Data2&&
    Data3 == id.Data3&&memcmp(Data4,id.Data4,sizeof(id.Data4)) ==0 )
    return true;
   return false;
  }
  friend ostream& operator<<(ostream &os,const lg_GUID &id);
 };
}
#endif

//////////////////////////////////////////////////////////////CPP///////////////////////////////////////////////////////////
#include "stdafx.h"
#include "lg_guid.h"
namespace lglib
{
 static lg_ComEnv __ComEnv;
 
 lg_GUID::lg_GUID()
 {
  Change();  
 }
 
 lg_GUID::lg_GUID(const GUID& id)
 {
  *this = id;
 }

 lg_GUID::lg_GUID(const lg_GUID& id)
 {
  *this = id;
 }
 
 lg_GUID::~lg_GUID(){}

 void lg_GUID::Change()
 {
  GUID id;
  ::CoCreateGuid(&id);
  *this = id;
 }
 void lg_GUID::print(OutputType type)
 {
  LGTRACE(type,"{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
   Data1, Data2, Data3,
   Data4[0], Data4[1], Data4[2], Data4[3],
   Data4[4], Data4[5], Data4[6], Data4[7]);
 }
 ostream& operator<<(ostream &os,const lg_GUID &id)
 {
  char chOut[40];
  sprintf(chOut,"{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
   id.Data1, id.Data2, id.Data3,
   id.Data4[0], id.Data4[1], id.Data4[2], id.Data4[3],
   id.Data4[4], id.Data4[5], id.Data4[6], id.Data4[7]);
  os<<chOut<<endl;
  return os;
 }

}

posted on 2006-05-16 14:01 龙仪 阅读(1795) 评论(10)  编辑 收藏

评论

# re: 代码库之十二-GUID类 2006-05-16 15:42 清风雨

我向来比较懒惰,所以,又没有细看。
不过,在C++里,有 type operator( void )
你可以:
int operator( void ) const
{
    return guid;
}
其实,我不推荐你这么玩啦,只是比写很多代码省事。^_^

# re: 一个对象要让map使用有一些条件的 2006-05-16 15:47 清风雨

是的,机会所有的STL算法都是对对象类有operator的要求的。刘未朋说,GP是基于结构和特性的 —— 比如,map里的key要求的operator <就是一种特性。
除了常用的operator操作符外,还有一个成为functor的T operator()(...)的操作符。

# 不好意思,写错了 2006-05-16 15:52 清风雨

应该是operator type( void )
operator int( void ) const

另外,我发言经常容易打别字,这个就容忍一下,谢谢了!

机会——》几乎
成为——》称为

# re: 代码库之十二-GUID类 2006-05-16 18:02 周星星

为什么不使用 map 的第三个模板参数?
这样就能保证 GUID 的“清白” ^_^

# re: 代码库之十二-GUID类 2006-05-16 18:43 Diviner

写一个GUID类确实也不错,下面是星星提到的那种模板参数,也可以
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <map>
#include <string>

struct GuidLessThanClass : public std::binary_function<GUID,GUID,bool>
{
bool operator()(const GUID& left, const GUID& right) const
{
return true;
}
};

int main(int argc,char *argv[])
{
std::map<GUID,std::string,GuidLessThanClass> MyGuidToString;
return 0;
}

# re: 代码库之十二-GUID类 2006-05-16 21:01 hpho

#include <map>
#include <string>
#include <cstdlib>
#include <basetyps.h>

// 记忆中重载operator <就OK了吧!
bool operator <(GUID const& lhs, GUID const& rhs){
     return 0;
}

int main(){
    using namespace std;
    typedef pair<GUID, string> pair;
    typedef map<pair::first_type, 
                pair::second_type> map;
    map m;
    m.insert(pair(GUID(), "vck"));
    system("pause");
    return 0;
}

# re: 代码库之十二-GUID类 2006-05-16 21:20 hpho

1, 既然有 lg_GUID(const GUID& id); 且不是explicit那么
   inline void operator=(const GUID& id)和
   inline bool operator==(const GUID& id) const在设计上可以说是沉余的, 当然这样做也有它的效率(减少临时对象). 
其实建议还不如直接class __LGLIB__ lg_GUID:pulbic GUID

2, operator==(const lg_GUID& id)理论上要检查一下是否this==&id, 并且它应该是重载为友员方式, 那个print()也应该改为ostream operaor<<(ostream& os, lg_GUID const& id)

3, void lg_GUID::Change()
 {
  GUID id;
  ::CoCreateGuid(&id);
/*
  Data1 = id.Data1;
  Data2 = id.Data2;
  Data3 = id.Data3;
  memcpy(Data4,id.Data4,sizeof(Data4)); 
*/
  *this=id; // 为什么不用简单的呢?
 }

4, 那个宏应该考虑有重复定义的情况, 即提供一个非宏的版本.

# re: 代码库之十二-GUID类 2006-05-17 10:10 Diviner

因为我比较讨厌重载操作符,看起来不太爽

# re: Diviner 2006-05-17 13:11 清风雨

在C++里,适度采用operator,实际会使得代码看起来更舒服。
比如:
std::for_each( iter_begin,iter_end,functor() );
通过functor的这个写法,要比
for( iter = iter_begin;iter != iter_end;++iter ) ...
看起来舒服,实际调试也更方便(相对而言,只需要关注functor)
point p1,p2,p3 = p1 + p2;
在java的思想下,这种方式是不好的,采用语言强力支持的概念,更清晰(java反对操作符重载,没有提供支持)。
但,在C++里,这种看起来也是比较自然的。
所以,因地制宜!—— 象我这种懒人,在C++里,operator可以使我少打很多字。

# re: 代码库之十二-GUID类(0.1) 2008-05-27 11:58 充电器

好东西,谢谢分享

标题  
姓名  
主页
验证码 *
内容   
  登录  使用高级评论  Top
[使用Ctrl+Enter键可以直接提交]