闲人

君子性非异也 善假于物也
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

实现垫片类--下

Posted on 2006-01-04 22:24  闲人  阅读(770)  评论(0编辑  收藏  举报

    时间过得真快,记得写实现垫片类--上的问题时候,想好一个星期以后补全的,怎么转眼2个月就过去了...自己真是个懒啊!!今天我把垫片类写完吧。
    函数对象很好的解决了垫片类的实现问题,但是不得不引入了一个很恶心的宏,那有没有办法连宏都避免呢?
    如果要避免宏,那么_UNCC必须是类名,_UNCC(szEditText)也就只是简单的构造了一个临时的类实例,调用的函数也只有构造函数。什么?让构造函数直接返回一个wchar_t*类型?这怎么可能呢.....
    不过深入想象一下,如果我们只是做到这里,系统会怎么做呢?显然,编译器要尝试把临时创建的_UNCC类对象,隐式转化为wchar_t*类型,但是肯定会转换失败的,因为系统不知道这两种类型该如何转换,那我给_UNCC类手动添加类型转换,岂不是就能解决问题了?
    C++类支持类型转换,他把类型转换当作一个一元操作符来处理。那么,给我们的_UNCC类添加一个向wchar_t*类型的转换支持,就需要在_UNCC类的实现里加上类型转换函数了,这个函数很可能是这样的:
    operator wchar_t*();
    到此为止,垫片类的实现就一目了然了吧。

    相应的,例子就可以改成下面的形式了:

#include <iostream>
#include <string>
using namespace std;

class _A
{
public:

 _A():m_p(NULL)
 {
 }

 ~_A()
 {
  if (NULL != m_p)
  {
   delete[] m_p;
  }
 }

 _A(string s):m_p(NULL)
 {
  m_p = new char[s.length() + 1];
  strcpy(m_p, s.c_str());
 }

 _A(const char *s):m_p(NULL)
 {
  if (NULL == s)
  {
   m_p = new char[1];
   *m_p = 0;
  }
  else
  {
   m_p = new char[strlen(s) + 1];
   strcpy(m_p, s);
  }
 }

 _A(long s):m_p(NULL)
 {
  m_p = new char[9];
  sprintf(m_p, "%ld", s);
 }

 operator char*()
 {
  return m_p;
 }

private:

 char* m_p;

};

void PrintStr(const char* s)
{
 cout<<s<<endl;
}

int main(int argc, char* argv[])
{
 string s("I'm a C++ string");

 PrintStr(_A(s));
 
 PrintStr(_A("I'm a C++ string"));

 PrintStr(_A(4234234));

 return 0;
}

    顺便提一句,垫片类很好用,在涉及到临时类型转换的地方,我建议多采用垫片类实现,一来可以避免大量重复的类型转化代码的书写,二来也可以避免内存泄露。同时也建议,垫片类命名采用下划线+大写类名的形式,以告知程序员,我是一个垫片类。

闲人,2006.1.4