In the previous articles, we added namespace optimizations to add event functionality. That's enough for me. But you can also add a property feature.
When we change a property in C + +, it's usually a get function plus a set function, but it's not easy to write a member variable directly. For example:
1);
No
A.value = A.value + 1;
Convenient.
However, this convenience can only be used if you invoke an object with property functionality. I used the old routine to write a get and set function when I created the property, and what to do or what to do. My property function is actually to add a common member in the class, read the data member when the call get method, assign the member to call the set method, of course, this member in the initialization of the Get and set function of the pointer pass in and can not change, Because I think there is no need to think about changing the function of these things that cannot happen.
Well, the idea is clear, now it's time to paste the code.
Template <typename t>classiproperty{ Public: Virtual ConstT & Get ()Const=0; VirtualT & Reference () =0; Virtual voidSet (ConstT &) =0;}; Template<typename t>classProperty: PublicIproperty<t>{ Public: usingSelf = property<t>; usingGetconstanteventhandler = delegate<ConstT &>; usingGetnotconstanteventhandler = Delegate<t &>; usingGetvalueeventhandler = delegate<t>; usingsetEventHandler = delegate<void,ConstT &>; Public: Property () {} template<typename tclasstype>Property (Tclasstype* ClassName,ConstT & (Tclasstype::* getconstantfunction) ()Const, T & (tclasstype::* getnotconstantfunction) (),void(Tclasstype::* setfunction) (ConstT &value)) {Clear (); Mgetconstant.add (ClassName, getconstantfunction); Mgetnotconstant.add (ClassName, getnotconstantfunction); Mset.add (ClassName, setfunction); } template<typename tclasstype>Property (Tclasstype* ClassName,ConstT & (Tclasstype::* getconstantfunction) ()Const, T & (Tclasstype::*getnotconstantfunction) ()) {Clear (); Mgetconstant.add (ClassName, getconstantfunction); Mgetnotconstant.add (ClassName, getnotconstantfunction); } template<typename tclasstype>Property (Tclasstype* ClassName,ConstT & (Tclasstype::* getfunction) ()Const,void(Tclasstype::* setfunction) (ConstT &value)) {Clear (); Mgetconstant.add (ClassName, getfunction); Mset.add (ClassName, setfunction); } template<typename tclasstype>Property (Tclasstype* ClassName, T & (tclasstype::* getfunction) (),void(Tclasstype::* setfunction) (ConstT &value)) {Clear (); Mgetnotconstant.add (ClassName, getfunction); Mset.add (ClassName, setfunction); } template<typename tclasstype>Property (Tclasstype* ClassName,ConstT & (Tclasstype::* getfunction) ()Const) {Clear (); Mgetconstant.add (ClassName, getfunction); } template<typename tclasstype>Property (Tclasstype* ClassName, T & (Tclasstype::*getfunction) ()) {Clear (); Mgetnotconstant.add (ClassName, getfunction); } template<typename tclasstype>Property (Tclasstype*classname,void(Tclasstype::*setfunction) ()) {Clear (); Mset.add (ClassName, setfunction); } Public: voidClear () {mgetconstant.removeall (); Mgetnotconstant.removeall (); Mgetvalue.removeall (); Mset.removeall (); } ConstT & Get ()Const Override { if(Isconstreferencegetable ()) {returnMgetconstant.invoke (); } Else { Throw "Constant reference cannot get"; }} T& Reference ()Override { if(Isreferencegetable ()) {returnMgetnotconstant.invoke (); } Else { Throw "cannot get"; } } voidSet (ConstT & Value)Override { if(Issetable ()) {Mset.invoke (value); } Else if(Isreferencegetable ()) {Reference ()=value; } Else { Throw "Cannot set"; } } BOOLIsgetable ()Const { returnIsconstreferencegetable () | |isreferencegetable (); } BOOLIsconstreferencegetable ()Const { returnMgetconstant.getcount () >0; } BOOLIsreferencegetable ()Const { returnMgetnotconstant.getcount () >0; } BOOLIssetable ()Const { returnMset.getcount () >0||isreferencegetable (); } operator ConstT & ()Const { returnGet (); } Self&operator= (ConstT &value) {Set (value); return* This; }Private: Getconstanteventhandler mgetconstant; Getnotconstanteventhandler mgetnotconstant; Getvalueeventhandler Mgetvalue; setEventHandler MSet;}; Template<typename t>classBasicproperty:iproperty<t>{ Public: usingSelf = basicproperty<t>; Public: Basicproperty () {} basicproperty (ConstT &value): Mvalue (value) {} Public: ConstT & Get ()Const Override { returnMvalue; } T& Reference ()Override { returnMvalue; } voidSet (ConstT &value) {Mvalue=value; } operator ConstT & ()Const { returnGet (); } Self&operator= (ConstT &value) {Set (value); return* This; }Private: T mvalue;};
The code looks a lot, in fact, two classes, a property, in the initialization of the Get and set functions to pass in (of course, can also pass some of the functions optimized for efficiency, unfortunately these functions are too anti-human, and some do not), of course, flawed, I do not overload +=,-=,*=,/= These operators are a big mishap, too. There is a basicproperty, a simple package of data, no get,set and other methods, in my opinion is very common.
Alas, how to say, this time I add attribute this function actually I think is superfluous. In C + + it is entirely possible to do this with the Get,set method, even if there is a property feature that is not commonly used. And it doesn't save much. But some languages have this function when it is written to play it.