能夠看到一個屬性被分解成三塊:域(Field)、getter和setter、存取器(Accessor)。
Field是C#類的成員變量被定義的地方,對應C++也是類的成員變量定義(可訪問性爲:private);
getter和setter是C#類的成員函數,對應C++也是類的成員函數(可訪問性爲:private、protect或者public);
Accessor纔是C#真正實現屬性語法的地方(以下圖所示),對應C++能夠使用operator運算符實現。
若是僅僅考慮前兩條,用C++很容易的就能使用宏展開模仿出來:
#define AutoProperty(ValueType, GetAccessor, SetAccessor, Variable) private: ValueType Variable;\
GetAccessor: ValueType get##Variable() { return Variable; }\
SetAccessor: void set##Variable(ValueType newValue) { Variable = newValue; }
AutoProperty分爲四個部分:ValueType是變量的類型;GetAccessor、 SetAccessor分別是getter和setter的可訪問性;Variable是變量的名稱。AutoProperty使用起來很是簡單:
// 任務是否能夠運行,只讀屬性
AutoProperty(bool, public, protected, CanRun);
可是當外部或子類使用如上定義的CanRun屬性的時候,卻只能經過getCanRun()和setCanRun()這一對成員函數,而不像C#那樣簡單。
下面咱們考慮用C++模擬出C#的 Accessor實現的功能。
#include <functional>
using namespace std;
template<typename ValueType>
class Property
{
protected:
typedef function<ValueType()> GetterType;
GetterType getter;
typedef function<void(ValueType)> SetterType;
SetterType setter;
public:
explicit Property(GetterType gt, SetterType st) : getter(gt), setter(st) {}
operator ValueType() { return getter(); }
Property& operator = (ValueType value) { setter(value); return *this; }
};
#define AutoProperty(ValueType, Variable) \
public: Property<ValueType> Variable;\
private: ValueType var##Variable;\
private: ValueType get##Variable() { return var##Variable; }\
private: void set##Variable(ValueType newValue) { var##Variable = newValue; }\
#define AutoPropertyImpl(Variable, Value) \
var##Variable(Value), Variable(bind(&A::get##Variable, this), bind(&A::set##Variable, this, placeholders::_1))
class A
{
public:
// 任務是否能夠運行,只讀屬性
AutoProperty(bool, CanRun);
public:
A() : AutoPropertyImpl(CanRun, true)
{}
};
int main(int argc, char* argv[])
{
A a;
bool b = a.CanRun;
a.CanRun = false;
return 0;
}
上面的這一段代碼是能夠正確運行的,也就是說我成功了。 PS:本篇文章對應的是自動完成屬性的模仿,對於普通屬性的模仿,等待個人下一篇文章吧。