If I need to write a setter and/or getter for a property I write it like this:
struct X { /*...*/};
class Foo
{
private:
X x_;
public:
void set_x(X value)
{
x_ = value;
}
X get_x()
{
return x_;
}
};
However I have heard that this is the Java style of writing setters and getters and that I should write it in C++ style. Moreover I was told it is ineficient and even incorrect. What does that mean? How can I write the setters and getters in C++?
Assume the need for getters and/or setters is justified. E.g. maybe we do some checks in the setter, or maybe we write only the getter.
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.