时间过得真快,记得写实现垫片类--上的问题时候,想好一个星期以后补全的,怎么转眼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