To work around that, the common answer is a get function, eg:
Code: Select all
class Foo {
private: int value;
public: int getValue() const { return value; }
};
I also don't want it to act like something it's not, eg requiring a special set() function to assign to the variable is out of the question.
I've come up with a workaround:
Code: Select all
template<typename C>
class propertyClass {
public:
template<typename T>
class property {
public:
const T& operator()() const { return value; }
property() : value() {}
property(const T& newValue) : value(newValue) {}
protected:
operator T&() { return value; }
property& operator=(const T& newValue) { value = newValue; return *this; }
T value;
template<typename U> struct type_cast { typedef U type; };
friend class type_cast<C>::type;
};
};
class Foo : public propertyClass<Foo> {
public:
property<bool> bar;
Foo() { bar = true; } //this is valid
} foo;
int main() {
bool temp = foo.bar(); //this is valid
foo.bar = false; //... but this will cause an error
}
Code: Select all
template<typename T> struct foo { friend class T; }
Code: Select all
template<typename U> struct type_cast { typedef U type; };
friend class type_cast<C>::type;
But both of these methods have one obvious flaw: friends are not transitive. That is, no derived class can gain read-write access to a property defined in a base class, which is a problem for me as most of my processor classes use abstract base classes to define the interface.
So, I've run out of tricks here. Anyone think they can do something like the above, but with the ability to be inherited?