How to write C++ getters and setters

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.

Leave a Comment