9

I have two simple classes for working with 3d geometry Point and Vector. They both have 3 coordinates as public member variables and define some operators like +, -, * ....

class Point
{
public:
    double x, y, z;
    // ctor and some operators   
}


class Vector
{
public:
    double x, y, z;
    // ctor and some operators   
}

Is there any real argument against making the coordiantes public? I will never change double to any other type. I do not want to restrict the values of x, y, z to a special range and I do not want to check anything when setting the coordinates.

The classes are in a library which will be used by other projects.

Update:
For me a big disadanvtage of setters/getters would be to have to write/read code like this:

myVec.setX(myVec.x() + 1.0);

instead of

myVec.x += 1.0;

Upadate 2:
Qt uses getters/setters in QPoint but with no benefit

zboson
  • 121
  • 7
  • 2
    I would recommend to use struct instead class if you need public access. – Dmytro Dadyka Dec 15 '18 at 18:00
  • If you don't have any other member variables calculated based on x, y ,z, I see no reason to hide them. Btw, the `double x, y, z; ` in `Vector` should probably be `Point p;` – Ted Lyngmo Dec 15 '18 at 18:01
  • 1
    You don’t want to do any restrictions? So you’re fine with infinite and NaN values? – vandench Dec 15 '18 at 18:04
  • 1
    I plan to add some asserts in the constructors and operators. But it will not be a guaranteed conditon that the values are valid numbers. – zboson Dec 15 '18 at 18:06
  • 1
    Sounds good. Validating every time you you change the values would be costly. – Ted Lyngmo Dec 15 '18 at 18:08
  • 1
    I think `myVec.setX(myVec.x() + 1.0);` should be replaced by `myVec.shiftX(1.0);` from the view point of readability even though you set `x`, `y`, `z` as private. – Hiroki Dec 15 '18 at 18:51
  • Possible duplicate of [C++ getters/setters coding style](https://stackoverflow.com/questions/760777/c-getters-setters-coding-style) – xskxzr Dec 15 '18 at 19:36
  • 2
    You should define arithmetic for vectors and write `myVec.setX(myVec.x() + 1.0);` as `myVec += Vector(1,0,0);`. Client code almost never needs to care about the individual coordinates of a vector. – molbdnilo Dec 15 '18 at 20:49

2 Answers2

3

While at first it appears that there is no clear advantage to restrict visibility of class members, it may happen in the future.

For example, if in some future extension you want to add some attribute to the class whose value depend on the x,y,... values, it would be very valuable to have them in a private scope, so that it can get automatically re-computed.

Also, as @vandensh suggest, accessing data members through "getters" and "setters" can help detecting illegal values (see std::isnan ).

There cannot be a clear answer, it really depends on the use case.

kebs
  • 6,387
  • 4
  • 41
  • 70
  • If you want to guarantee that the object always has valid values you have to use setters for sure. In my case I don't want to throw an `exception` or anything like that if the values are invalid. The only thing I can think of is to add an `assert` to the setter. But the question is if it's worth to do it and only because of an `assert` to impose the burden to write/read code like this: `myVec.setX(myVec.x() + 1);` – zboson Dec 15 '18 at 18:23
  • Year, I use this a lot. I call this "overengineering". –  Dec 15 '18 at 18:47
  • 1
    As I said, no definitive answer, but if you want safety... then it comes at a price. – kebs Dec 15 '18 at 19:10
3

In C++, I will add setters and getters if only to conform to the Uniform Access Principle; why should the caller have to keep track of what is stored and what is computed?

When it comes to basic data types, where the only invariant is scope, I will happily admit that the extra effort might not be worth it. But something like a Range type (with .high, .low, .distance) where there is an invariant to be maintained (hight >= low, distance = high - low) then it's a necessity. Otherwise, all the clients of the type end up having to maintain the invariant when that should be the job of the type itself.

Daniel T.
  • 32,821
  • 6
  • 50
  • 72
  • That sounds absolutely reasonable, If your class does not have some invariants to maintain there is no real reason for me for setters and getters. – zboson Dec 16 '18 at 20:32
  • Yes there is. Consistency at the call site is a "real" reason. – Daniel T. Dec 17 '18 at 15:18