I was converting a struct to a class so I could enforce a setter interface for my variables.
I did not want to change all of the instances where the variable was read, though.
So I converted this:
struct foo_t {
int x;
float y;
};
to this:
class foo_t {
int _x;
float _y;
public:
foot_t() : x(_x), y(_y) { set(0, 0.0); }
const int &x;
const float &y;
set(int x, float y) { _x = x; _y = y; }
};
I’m interested in this because it seems to model C#’s idea of public read-only properties.
Compiles fine, and I haven’t seen any problems yet.
Besides the boilerplate of associating the const references in the constructor, what are the downsides to this method?
Any strange aliasing issues?
Why haven’t I seen this idiom before?
There is an aliasing issue in that because you expose a reference to the
foo_t‘s internal data, it’s possible for code external to afoo_tobject to hold on to references into its data beyond the object’s lifetime. Consider:Or, even simpler:
These aren’t particularly realistic examples, but this is a potential issue whenever an object exposes or returns a reference to its data (public or private). Of course, it’s just as possible to hold on to a reference to the
foo_tobject itself beyond its lifetime, but that might be harder to miss or to do by accident.Not that this is an argument against what you’re doing. In fact I’ve used this pattern before (for a different reason) and I don’t think there’s anything inherently wrong with it, aside from the lack of encapsulation, which you seem to recognize. The above issue is just something to be aware of.