C# Style Properties in C++?

I was in experimenting mood again. I got annoyed by writing the following code over and over again:

class Test {
private:
	int myVar;
public:
	int GetMyVar() { return myVar; }
}

Sometimes additionally to that a Setter method which processes or checks the values.

So how to make this more compact? With macro hacking! jippie! Yep macros are bad, but sometimes its nice to make some experiments, so here we go.

Simple read only properties

Well the most used case for me is: I want a property that can be read from the outside, but can only be written from “inside” the class.

So here we go:

class Test : EnableProperties<test> {
public:
	Property(ReadOnly, std::string) MyVar;
}

Uuuh, magic macro hacking. So what can we do now with this variable? With the operator() we can set and get the value of this property, but for ease of use we can also use implicit conversion.

Test test;
test.MyVar("New String"); // Access Error
std::string a = test.MyVar(); // Yep
std::string b = test.MyVar; // Fine too

Custom getter and setter

Lets just say we want to do process the value of the property on each get. With even more macro and template hacking we get this:

class Test : EnableProperties<test> {
public:
	CustomProperty(Public, int) {
		Getter {
			return value * 42;
		}
	} MyVar;
}
Test test;
test.MyVar(10);
std::cout << test.MyVar() << std::endl; // 420

I think this is a pretty funny experiment. There are still some issues left. For example: the custom getter and setter feature only works with VC. Still it is an very interesting concept and I think I will investigate it a little bit further.

Code

Want to see the strange macro hacking? Sure here you go :)

template<typename friendclass typename t,> class ReadonlyProperty {
protected:
	typedef T ValueType;

	friend FriendClass;
	ValueType value;

	virtual void Set(const ValueType& newValue) { value = newValue; }
	virtual const ValueType& Get() { return value; }

public:
	inline void operator()(const ValueType& newValue) { Set(newValue); }
	inline const ValueType& operator()() { return Get(); }
	inline operator ValueType() { return Get(); }
};

template<typename friendclass typename t,> class PublicProperty {
protected:
	typedef T ValueType;

	friend FriendClass;
	ValueType value;

public:
	virtual void Set(const ValueType& newValue) { value = newValue; }
	virtual const ValueType& Get() { return value; }

	inline void operator()(const ValueType& newValue) { Set(newValue); }
	inline const ValueType& operator()() { return Get(); }
	inline operator ValueType() { return Get(); }
};

template<typename t> class EnableProperties {
protected:
	typedef T PropertyFriendClass;
};

#define Property(Access, type) class : public Access##Property<type , PropertyFriendClass> {}
#define CustomProperty(Access, type) class : public Access##Property<type , PropertyFriendClass>

#define Setter virtual void Set(const ValueType& value)
#define Getter virtual const ValueType& Get()
This entry was posted in Experiments. Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.
  • http://www.bloodmoonunder.de Wemser

    Moin Dennis,
    nette Sache, so Properties für C++. Muss allerdings gestehen, dass ich die Funktionsweise der Magic Macros nicht vollständig raffe – dafür sind meine C++ Kenntnisse zu mies was Operatoren und Templates angeht.

    Aber das Konzept der Properties ist wunderbar! Kenn das von Objective-C und weiß es dort sehr zu schätzen!

    Viel Spass beim weiteren rumexperimentieren,
    Wemser

  • Dennis

    Moin Wemser!

    ObjC wäre eine Sprache die auch sehr gerne mal lernen würde. Eigentlich würde ich sogar sehr gerne vollständig auf C++ verzichten, aber was will man machen :D Muss man es sich halt so komfortabel wie möglich machen.

    Grüße,
    Dennis