Hi,
Unless I am thoroughly mistaken, the getter/setter pattern is a common pattern used for two things:
- To make a private variable so that it can be used, but never modified, by only providing a
getVariable
method (or, more rarely, only modifiable, by only providing asetVariable
method). - To make sure that, in the future, if you happen to have a problem to which a good solution would be simply to treat the variable before it goes in and/or out of the class, you can treat the variable by using an actual implementation on the getter and setter methods instead of simply returning or setting the values. That way, the change doesn't propagate to the rest of the code.
Question #1: Am I missing any use of accessors or are any of my assumptions incorrect? I'm not sure if I am correct on those.
Question #2: Are there any sort of template goodness that can keep me from having to write the accessors for my member variables? I didn't find any.
Question #3: Would the following class template be a good way of implementing a getter without having to actually write the accesor?
template <class T>
struct TemplateParameterIndirection // This hack works for MinGW's GCC 4.4.1, dunno others
{
typedef T Type;
};
template <typename T,class Owner>
class Getter
{
public:
friend class TemplateParameterIndirection<Owner>::Type; // Befriends template parameter
template <typename ... Args>
Getter(Args args) : value(args ...) {} // Uses C++0x
T get() { return value; }
protected:
T value;
};
class Window
{
public:
Getter<uint32_t,Window> width;
Getter<uint32_t,Window> height;
void resize(uint32_t width,uint32_t height)
{
// do actual window resizing logic
width.value = width; // access permitted: Getter befriends Window
height.value = height; // same here
}
};
void someExternalFunction()
{
Window win;
win.resize(640,480); // Ok: public method
// This works: Getter::get() is public
std::cout << "Current window size: " << win.width.get() << 'x' << win.height.get() << ".\n";
// This doesn't work: Getter::value is private
win.width.value = 640;
win.height.value = 480;
}
It looks fair to me, and I could even reimplement the get
logic by using some other partial template specialization trickery. The same can be applied to some sort of Setter or even GetterSetter class templates.
What are your thoughts?