C++垫片类(1)

来源:互联网 发布:培训机构 源码 编辑:程序博客网 时间:2024/04/28 14:36
 垫片类是通过C++的函数重载和运算符重载来实现某些特殊功能的类,这种类能够简化代码或者实现某些不能直接被C++支持的语法。
 函数重载使得一个垫片类可以通过多种方法来构造或修改;同时运算符重载可以将垫片类转换成若干种目标类型。
 例如我们调用CDC的函数DrawText
    //int CDC::DrawText(const CString& str, LPRECT lpRect, UINT nFormat);      dc.DrawText(_T("test"), CRect(10, 10, 100, 100), DT_SINGLELINE | DT_LEFT);
DrawText的第二个参数类型是LPRECT(即RECT*),但是我们传入一个CRect仍然可以通过。这是因为CRect定义了operator LPRECT(),这个函数会将CRect对象自动转换为LPRECT。如果没有这个运算符重载,那么上面的代码只能写为:
    //这里会调用CRect::operator LPRECT()      CRect rc(10, 10, 100, 100);    dc.DrawText(_T("test"), &rc, DT_SINGLELINE | DT_LEFT);

再在比如COM里频繁出现的HRESULT,需要调用SUCCEEDED和FAILED来判断操作结果。这种情况就可以写个垫片类来包装一下。
class cResult  {  public:      cResult(HRESULT c) : m_Code(c) {}      operator bool() const { return SUCCEEDED(m_Code); }      bool operator!() const { return FAILED(m_Code); }  private:      HRESULT  m_Code;  };    void foo()  {      cResult Result = CoInitialize(0);    if(Result)    {          // bla bla      }  }  


来个稍微复杂点的例子

//#include <string>  //#include <stdarg.h>  template<size_t BufferSize>  class cStringShim  {  public:      typedef    wchar_t        char_type;      typedef    std::wstring   string_type;      enum { BUFFER_SIZE = BufferSize, };    public:      inline cStringShim()      {          m_Buffer[0] = 0;      }      inline cStringShim(const char_type* Format, ...)      {          va_list Arguments;          va_start(Arguments, Format);          _vsnwprintf_s(m_Buffer, BUFFER_SIZE, _TRUNCATE, Format, Arguments);      }      inline cStringShim(int v, const char_type* Format = 0)      {          (*this)(Format ? Format: L"%d", v);      }      inline cStringShim(float v, const char_type* Format = 0)      {          (*this)(Format ? Format: L"%f", v);      }      inline cStringShim& operator()(const char_type* Format, ...)      {          va_list Arguments;          va_start(Arguments, Format);          _vsnwprintf_s(m_Buffer, BUFFER_SIZE, _TRUNCATE, Format, Arguments);          return *this;      }      inline cStringShim& operator()(int v, const char_type* Format = 0)      {          return (*this)(Format ? Format: L"%d", v);      }      inline cStringShim& operator()(float v, const char_type* Format = 0)      {          return (*this)(Format ? Format: L"%f", v);      }      inline operator const char_type*() const    { return m_Buffer; }      inline operator string_type() const         { return m_Buffer; }      inline const char_type* c_str() const       { return m_Buffer; }      inline string_type str() const              { return m_Buffer; }  private:      cStringShim(const cStringShim& rhs);      cStringShim& operator=(const cStringShim& rhs);  private:    char_type    m_Buffer[BUFFER_SIZE];  };

下面是用法(由于cStringShim只处理了int、float,而没有处理double。所以浮点数必须是float类型,否则编译器不知道该将double转换成int还是float) 
cStringShim<1024> ss;  ::SetWindowText(hWnd, ss(12345));  ::SetWindowText(hWnd, ss(123.45f));  ::SetWindowText(hWnd, cStringShim<1024>(12345));  ::SetWindowText(hWnd, cStringShim<1024>(123.45f));