而自定义get/set函数,就让用户重写=操作符和自定义转换操作符就可以了。但是深入一想有一个大麻烦。自定义get/set函数的一个重要目的就是设置边界条件或者检查。如果这种检查不依赖对象的其它值(准确的说是非静态变量),问题还不大,但是实际中要依赖对象的其它值的情况也是相当普遍的,那么,就需要获得使用这个属性的对象指针。关于这个问题实在不好很完美的解决。
现在我的解决方案是使用一个基类存放使用属性的对象的指针,但是这样便涉及多处需要插入代码的局面。如果大家有更好的方法,欢迎和我交流。
第二版的宏定义如下:
#ifdef USE_PROPERTY
#define DECLARE_PROPERTY(ClassName) typedef ClassName HostClass;
class PropertyBase...{
public: inline static void SetPPOwner(HostClass* thispoint)...{PPOwner=thispoint;}
protected:
static HostClass* PPOwner;
};
#define BasicProperty(TYPE,NAME,REFObj) class TYPE##Property_##NAME :PropertyBase{
public:
inline TYPE operator=(TYPE value)...{PPOwner->REFObj=value;return value;}
inline operator TYPE()...{return PPOwner->REFObj;}
};
TYPE##Property_##NAME NAME;
//End of BasicProperty define.
#define ComplexProperty(TYPE,NAME) class TYPE##Property_##NAME :PropertyBase{
public:
TYPE operator=(TYPE ac);
operator TYPE();
};
TYPE##Property_##NAME NAME;
//End of ComplexProperty define.
//ComplexProperty should use Marco Setor and Getor to define its own get/set behavior
#define IMPLEMENT_PROPERTY(ClassName) typedef ClassName HostClass;
HostClass* HostClass::PropertyBase::PPOwner=NULL;
#define PROPERTYBASE_INIT PropertyBase::SetPPOwner(this);
#define Setor(TYPE,NAME) TYPE HostClass::TYPE##Property_##NAME::operator=(TYPE value)
#define Getor(TYPE,NAME) HostClass::TYPE##Property_##NAME::operator TYPE()
#define Property(TYPE,NAME,REFObj) BasicProperty(TYPE,NAME,REFObj)
#define CProperty(TYPE,NAME) ComplexProperty(TYPE,NAME)
#else
#define DECLARE_PROPERTY(ClassName)
#define IMPLEMENT_PROPERTY(ClassName)
#define BasicProperty(TYPE,NAME,REFObj)
#define ComplexProperty(TYPE,NAME)
#define PROPERTYBASE_INIT
#endif
要使用的话,首先要define USE_PROPERTY。然后在类的定义的开始部分插入一行DECLARE_PROPERTY(ClassName),在类的实现之前插入一行IMPLEMENT_PROPERTY(ClassName),并在类的所有构造函数中插入一行PROPERTYBASE_INIT。(大家应该看得出来我这是模仿的MFC的某些宏)
