Does C++11 have C#-style properties?
In C#, there is a nice syntax sugar for fields with getter and setter. Moreover, I like the auto-implemented properties which allow me to write
public Foo foo { get; private set; }
In C++ I have to write
private:
Foo foo;
public:
Foo getFoo() { return foo; }
Is there some such concept in the C++11 allowing me to have some syntax sugar on this?
In C++ you can write your own features. Here is an example implementation of properties using unnamed classes. Wikipedia article
struct Foo
{
class {
int value;
public:
int & operator = (const int &i) { return value = i; }
operator int () const { return value; }
} alpha;
class {
float value;
public:
float & operator = (const float &f) { return value = f; }
operator float () const { return value; }
} bravo;
};
You can write your own getters & setters in place and if you want holder class member access you can extend this example code.
C++ doesn't have this built in, you can define a template to mimic properties functionality:
template <typename T>
class Property {
public:
virtual ~Property() {} //C++11: use override and =default;
virtual T& operator= (const T& f) { return value = f; }
virtual const T& operator() () const { return value; }
virtual explicit operator const T& () const { return value; }
virtual T* operator->() { return &value; }
protected:
T value;
};
To define a property:
Property<float> x;
To implement a custom getter/setter just inherit:
class : public Property<float> {
virtual float & operator = (const float &f) { /*custom code*/ return value = f; }
virtual operator float const & () const { /*custom code*/ return value; }
} y;
To define a read-only property:
template <typename T>
class ReadOnlyProperty {
public:
virtual ~ReadOnlyProperty() {}
virtual operator T const & () const { return value; }
protected:
T value;
};
And to use it in class Owner
:
class Owner {
public:
class : public ReadOnlyProperty<float> { friend class Owner; } x;
Owner() { x.value = 8; }
};
You could define some of the above in macros to make it more concise.
There is nothing in the C++ language that will work across all platforms and compilers.
But if you're willing to break cross-platform compatibility and commit to a specific compiler you may be able to use such syntax, for example in Microsoft Visual C++ you can do
// declspec_property.cpp
struct S {
int i;
void putprop(int j) {
i = j;
}
int getprop() {
return i;
}
__declspec(property(get = getprop, put = putprop)) int the_prop;
};
int main() {
S s;
s.the_prop = 5;
return s.the_prop;
}
You can emulate getter and setter to some extent by having a member of dedicated type and overriding operator(type)
and operator=
for it. Whether it's a good idea is another question and I'm going to +1
Kerrek SB's answer to express my opinion thereon :)
With C++11 you can define a Property class template and use it like this:
class Test{
public:
Property<int, Test> Number{this,&Test::setNumber,&Test::getNumber};
private:
int itsNumber;
void setNumber(int theNumber)
{ itsNumber = theNumber; }
int getNumber() const
{ return itsNumber; }
};
And here ist the Property class template.
template<typename T, typename C>
class Property{
public:
using SetterType = void (C::*)(T);
using GetterType = T (C::*)() const;
Property(C* theObject, SetterType theSetter, GetterType theGetter)
:itsObject(theObject),
itsSetter(theSetter),
itsGetter(theGetter)
{ }
operator T() const
{ return (itsObject->*itsGetter)(); }
C& operator = (T theValue) {
(itsObject->*itsSetter)(theValue);
return *itsObject;
}
private:
C* const itsObject;
SetterType const itsSetter;
GetterType const itsGetter;
};