自定义类型转换函数 operator TYPENAME()

1.    VAssist插件不能实时检测using namespace XXX的语句,如果cpp文件中用到了自定义的namespace必须在类的定义处列出完整的namespace而不能用using namespace语句才能确保VAssistX正常解析上下文菜单。(最后还是不用VA了。。感觉用using namespace XXX语句还是比较方便)

2.    ClassX::GetData(){return m_data;} 必须在函数后面加上const限定符 否则无法接受const ClassX &型的参数,会提示“this指针无法从onst ClassX 转化为ClassX &”。

3.    用户自定义的类型转换函数:

//////////// header文件 //////////////////////

   class Font

   {

   public:

      Font();

      Font(CString stName, int iSze);

      Font(const LOGFONT& logFont);

      Font(const Font& font);

      //用户定义的类型转换函数(见《C++JAVA比较教程》pp371):

      operator LOGFONT() const{return m_logFont;} //必须限定为const函数才能接受const&型类实例变量.

      operator PLOGFONT() {return &m_logFont;} //m_logFont不是const,operator PLOGFONT()也不应该加const否则出错:“无法转换” 

      Font PointsToMeters() const;

      Font& operator =(const Font& font);

      BOOL operator ==(const Font& font) const;

      BOOL operator!=(const Font& font) const;

      void Serialize(CArchive& archive);

      BOOL IsItalic() const {return m_logFont.lfItalic;}

   private:

      LOGFONT m_logFont;

   };

 

////////////////////////////////////////////////

 

Font::Font(CString stName, int iSze)

{

   ::memset(&m_logFont,0,sizeof(m_logFont));

   wcscpy_s(m_logFont.lfFaceName,stName);

   m_logFont.lfHeight = iSze;

}

 

Font::Font(const LOGFONT& logFont)

{

   m_logFont=logFont;

}

 

Font Font::PointsToMeters() const

{

   LOGFONT logFont = m_logFont;

   logFont.lfWidth = (int)((double)2540*logFont.lfWidth/72);

   logFont.lfHeight = (int)((double)2540*logFont.lfHeight/72);

   return Font(logFont);

}

 

Font& Font::operator =(const Font& font)

{

   m_logFont=static_cast<LOGFONT>(font);//系统调用了自定义的operator LOGFONT()实现了类型转换

   return *this;

}

 

BOOL Font::operator == (const Font &font) const

{

   return  (::memcmp(&m_logFont,&font.m_logFont,sizeof(m_logFont)) == 0);

}

 

BOOL Font::operator !=(const Font& font) const

{

   return !(*this==font);

}

 

void Font::Serialize(CArchive& archive)

{

   if (archive.IsStoring())

   {

      archive.Write(&m_logFont,sizeof(m_logFont));

   }

   if (archive.IsLoading())

   {

      archive.Read(&m_logFont,sizeof(m_logFont));

   }

}

 

////////////////////////////////////////////

 

注:另外一种写法

operator PLOGFONT() const {return const_cast<PLOGFONT>(&m_logFont);} //将返回值(const LOGFONT*型,即pointer to const LOGFONT)进行const_cast成PLOGFONT(即LOGFONT*)后(去掉了const属性)才不会与operator PLOGFONT()的const冲突.   但这种做法违背了operator PLOGFONT()后面的const的本意(即函数后的const自动为函数体内的成员变量加上了const属性,表示PLOGFONT不应该修改成员变量)。

 

 

实际上利用typedef就可以正确实现到const LOGFONT*类型的自定义转换

 

typedef const LOGFONT* CPLOGFONT;

operator CPLOGFONT() const{return &m_logFont;}

 

注意这也是typedef比#define的区别之一:typedef可定义const修饰的类型,而#define仅仅是进行符号替换. 前者operator CPLOGFONT()表明函数返回值是CPLOGFONT类型,而后者在operator CPLOGFONT()处展开后得到的是operator const PLOGFONT()属于违法的函数定义

 

posted on 2009-05-15 23:52  TobyLin的学习之路  阅读(675)  评论(0编辑  收藏  举报

导航