A long time ago when I was working on Borland C++ and Delphi was just a baby, we added properties as a language extension to C++. Nobody at the C++ committee liked the notion (not sure why, but Java didn't like it either), but I came up with a way of doing properties in C++ using templates. Here is the property class:
enum PropertyType {READ_ONLY, WRITE_ONLY, READ_WRITE};
template <typename Container, typename ValueType, PropertyType Type>
class Property {
private:
Container* FObject;
void (Container::*FSetter)(ValueType value);
ValueType (Container::*FGetter)();
public:
Property() {
FObject = NULL;
FSetter = NULL;
FGetter = NULL;
}
void InitializeSetterGetter(Container* Value,
void (Container::*Setter)(ValueType Value),
ValueType (Container::*Getter)()) {
assert(Type == READ_WRITE);
FObject = Value;
FSetter = Setter;
FGetter = Getter;
}
void InitializeSetter(Container* Value,
void (Container::*Setter)(ValueType Value)) {
assert(Type == WRITE_ONLY);
FObject = Value;
FSetter = Setter;
}
void InitializeGetter(Container* Value,
ValueType (Container::*Getter)()) {
assert(Type == READ_ONLY);
FObject = Value;
FGetter = Getter;
}
// To set the value using the set method.
ValueType operator =(const ValueType& Value) {
assert(FObject != NULL);
assert(FSetter != NULL);
(FObject->*FSetter)(Value);
return Value;
}
// The Property class is treated as the internal type.
operator ValueType() {
assert(FObject != NULL);
assert(FGetter != NULL);
return (FObject->*FGetter)();
}
};
Now, to use this, call one of the Initializer* functions from within your classes constructor, provide getter and setter methods and instantiate the property as follows:
class TestProperty {
protected:
std::string FMyProperty;
public:
TestProperty() {
MyProperty.InitializeGetter(this,
&TestProperty::SetMyProperty
&TestProperty::GetMyProperty);
}
std::string GetMyProperty() {
return FMyProperty;
}
void SetMyProperty(std::string Value) {
FMyProperty = Value
}
Property<Process, std::string, READ_WRITE> MyProperty;
};
It's a bit more work than if you were to use a language that supports properties such as Delphi or C#, but it can be a very handy syntactic sugar.
No comments:
Post a Comment