There are two distinct forms of “properties” that turn up in the standard library, which I will categorise as “Identity oriented” and “Value oriented”. Which you choose depends on how the system should interact with Foo
. Neither is “more correct”.
Identity oriented
class Foo { X x_; public: X & x() { return x_; } const X & x() const { return x_; } }
Here we return a reference to the underlying X
member, which allows both sides of the call site to observe changes initiated by the other. The X
member is visible to the outside world, presumably because it’s identity is important. It may at first glance look like there is only the “get” side of a property, but this is not the case if X
is assignable.
Foo f; f.x() = X { ... };
Value oriented
class Foo { X x_; public: X x() const { return x_; } void x(X x) { x_ = std::move(x); } }
Here we return a copy of the X
member, and accept a copy to overwrite with. Later changes on either side do not propagate. Presumably we only care about the value of x
in this case.