为了方便演示,让我们先随便假定一个简单的应用场景:假定在我们的应用场景中有一个叫worker的类,它可以保存某个工人的名字,并在需要时打印出这个名字,它的源码如下:
class worker {
char mMyName[100];
bool mMyNameIsValid;
public:
worker(const char * name) {
if (name) {
strcpy(mMyName, name);
mMyNameIsValid = true;
} else {
mMyNameIsValid = false;
}
void sayHello() {
if (mMyNameIsValid)
std::out << "hello, my name is " << mMyName << std::endl;
else
std::out << "uh...do you know who am I?" << std::endl;
}
};
下面是主程序的源码:
int main(int argc, char * args[]) {
for (int i = 1; i < argc; ++i) {
worker someone(args[i]);
someone.sayHello();
}
return 0;
}
下面,我们就来修改这个程序,以期待我们可以在不修改新的worker对象的实现和主程序的情况下,可以动态的植入日志。首先,我们需要定义这个worker类的元类,其中的第一步是考虑如何定义它的成员函数的问题。观察原来的worker类,它只有一个构造函数和一个sayHello函数,这两个函数都是无返回值的,回想我们之前meta_meta_closure的定义,它的模板参数中需要定义返回值类型,那么我们要如何定义无返回值的函数呢?这里需要一点模板特化的技术:
首先,我们需要定义一个表示无类型的类:
struct void_type {
};
然后,我们定义一个模板来取代sizeof():
template<typename T>
struct size_detector {
enum {
TYPE_SIZE = sizeof(T)
};
};
同时,我们需要特化模板参数为void_type的情况:
template<>
struct size_detector<void_type> {
enum {
TYPE_SIZE = 0
};
};
接下来,我们再定义一个新的arg_wrapper:
template<typename arg_type, typename ret_type>
struct arg_wrapper {
arg_type args;
ret_type retVal;
};
同样,我们需要特化模板参数为void_type的情况:
template<typename arg_type>
struct arg_wrapper<arg_type, void_type> {
arg_type args;
};
template<typename ret_type>
struct arg_wrapper<void_type, ret_type> {
ret_type retVal;
};
template<>
struct arg_wrapper<void_type, void_type> {
};
最后,我们需要修改一下meta_meta_closure:
template <typename closure_traits>
struct meta_meta_closure: meta_closure {
typedef typename closure_traits::arg_type arg_type;
typedef typename closure_traits::ret_type ret_type;
typedef arg_wrapper<arg_type, ret_type> arg_wrapper_type;
virtual size_t argSize() const {
return size_detector<arg_type>::TYPE_SIZE;
}
virtual size_t retSize() const {
return size_detector<ret_type>::TYPE_SIZE;
}
virtual void closureEntry(arg_wrapper_type * argWrapper) = 0;
virtual void closureEntry(void * args) {
this->closureEntry( static_cast<arg_wrapper_type *>(args) );
}
这样我们就可以定义无参数或/且无返回值的函数对象了。下面给出meta_worker的完整定义:
class meta_worker: public runtime_class {
public:
// 定义对象的数据成员:
struct object_data {
char mMyName[100];
bool mMyNameIsValid;
};
// 因为每个成员函数都隐含了一个this指针参数,所以对每一个元函数的实现,其参数表中都需要一个this指针对应的参数,按照惯例我们总是将它命名为that
struct meta_method_args_base {
object_data * that;
};
// 定义构造函数的元函数:
struct meta_constructor_args: meta_method_args_base {
const char * name;
};
struct meta_constructor_traits {
typedef meta_constructor_args arg_type;
typedef void_type ret_type;
};
struct meta_constructor: meta_meta_closure<meta_constructor_traits> {
virtual const char * name() const {
static const char sName[] = "worker";
return sName;
}
virtual void closureEntry(arg_wrapper_type * argWrapper) {
if (argWrapper->name) {
strcpy(argWrapper->that->mMyName, argWrapper->name);
argWrapper->that->mMyNameIsValid = true;
} else {
argWrapper->that->mMyNameIsValid = false;
}
}
};
// 定义sayHello函数的元函数:
struct meta_say_hello_traits {
typedef meta_method_args_base arg_type;
typedef void_type ret_type;
};
struct meta_say_hello: meta_meta_closure<meta_say_hello_traits> {
virtual const char * name() const {
static const char sName[] = "sayHello";
return sName;
}
virtual void closureEntry(arg_wrapper_type * argWrapper) {
if (argWrapper->that->mMyNameIsValid)
std::out << "hello, my name is " << argWrapper->that->mMyName << std::endl;
else
std::out << "uh...do you know who am I?" << std::endl;
}
};
// 实现接口:
virtual const char * name() const {
static const char sName[] = "worker";
return sName;
}
virtual size_t dataSize() const {
return sizeof(object_data);
}
virtual size_t methodCount() const {
return 2;
}
virtual meta_closure ** methodTable() const {
static meta_closure * sMetaMethodTable[2];
sMetaMethodTable[0] = &mMetaConstructor;
sMetaMethodTable[1] = &mMetaSayHello;
return sMetaMethodTable;
}
virtual meta_closure * regCutPoint(meta_closure * target, bool enterOrLeave, meta_closure * cutPoint) {
int idx = (target == &mMetaConstructor)? 0: 1;
meta_closure ** cutPoints = enterOrLeave? mEnterPoints: mLeavePoints;
meta_closure * ret = cutPoints[idx];
cutPoints[idx] = cutPoint;
return ret;
}
// 该类本身的实现:
meta_worker() {
mEnterPoints[0] = mEnterPoints[1] = mLeavePoints[0] = mLeavePoints[1] = NULL;
}
private:
meta_constructor mMetaConstructor;
meta_say_hello mMetaSayHello;
meta_closure * mEnterPoints[2];
meta_closure * mLeavePoints[2];
};
现在,我们终于有了第一个元类的实现,让我们结合worker来理解一下这个元类,实际上,它就是对worker对象在内存中的结构以及成员函数的描述,请务必牢牢的记住并理解这一点,否则,可能会对接下来的代码示例产生误解。