Home c++ C++ get and set methods

C++ get and set methods

Author

Date

Category

There are about 50 variables in the class that are not related to each other, as it is recommended to place them in the private section, and in public to access them, you should already write get and set . But can this be done more conveniently? Since for me this lengthens the module itself and reduces the readability of the code, writing these methods for each variable … Isn’t it possible to do it more competently and conveniently so as not to write so much repetitive code?


Answer 1, authority 100%

This number of class members suggests bad design …

Regarding public and private . I would put it this way. If the members of the class are stable (you are not going to change the representation of the state) and are not bound to the invariant of the class, i.e. if their arbitrary change is not able to make the class itself invalid, then they can be made open. Classic example:

struct Point
{
  int x;
  int y;
};

Making Point with private members and functions to access them is overkill. No matter how you change x and y , it will still be the correct point.

If such a change in members can lead to the invalidation of the class – only private. For example, a (somewhat contrived) class that has an array of a certain size:

class Storage {
  private:
  int * array;
  int array_size;
...
};

Imagine that in the constructor you allocate memory for an array, store the number of elements in array_size – say, to restrict access. If now you can directly reach array or array_size and change them inconsistently – that’s it, your class will not understand what.

I would do something like this 🙂

But – again – 50 members per class is not a good sign …

And if you just want to write less – well, define a macro in the spirit of

DEF (type, var) private: type var; \
  public: type get _ ## var () const {return var; } \
      void set _ ## var (type val) {var = val; }

and you will have a class like

class Bedlam
{
  DEF (int, x)
  DEF (int, y)
  DEF (int, z)
  DEF (char, c)
  DEF (string, s)
...

Also an option …

P.S. If getters-setters are necessary and small – it is better to write them in the class declaration, then the compiler will be able to inline them, which is much more efficient than calling – if they are defined in a separate implementation file. They say that some keys of some compilers can cope in this case too :), but why complicate their work? ..


Answer 2, authority 40%

I have about 50 unrelated variables in my class

One of two things. Either your class is misdesigned, or it is not a class, but a data structure. In the first case, do some refactoring. The data in the class must be closely related to each other, and the class must perform one task (GRASP ). Perhaps you actually have a bunch of classes out of which you made a “chimera”. If this is a data structure with no behavior, then don’t worry, in this case getters and setters are not needed. The integrity of such a structure should be controlled by the code above.

Now about why you need it. Let’s say we have a class Rect :

class Rect {
  int _x1;
  int _y1;
  int _x2;
  int _y2;
public:
  int left () const {return _x1;}
  int right () const {return _x2;}
  int top () const {return _y2;}
  int bottom () const {return _y1;}
  int width () const {return _x2 - _x1;}
  int heigth () const {return _y2 - _y1;}
};

As you can see, it is specified by two dots. Let’s say after some time you decide that it would be better to set the rectangle not with two points, but with one point, height and width:

class Rect {
  int _x;
  int _y;
  int _width;
  int _heigth;
public:
  int left () const {return _x;}
  int right () const {return _x + _width;}
  int top () const {return _y + _heigth;}
  int bottom () const {return _y;}
  int width () const {return _width;}
  int heigth () const {return _heigth;}
};

The class interface remains the same despite the fact that the implementation has changed. In code that uses the Rect class, you don’t need to change a single line of code.

Since for me this lengthens the module itself and reduces the readability of the code,
write these methods for each variable

As you can see, a dozen lines of code saved us a lot of time and effort. And you don’t have to expose all your variables. It is enough to define an invariable interface, and what data you have there not to tell anyone. This concept is called encapsulation .

Isn’t it possible to do it more competently and conveniently?

The only thing that can make your life a little easier is modern IDEs that can generate methods for getting / setting values ​​automatically


Answer 3, authority 20%

In order not to decrease readability, divide the files into definitions (header files .h / .hpp) and implementation (.c / .cpp). It will be more intelligent and convenient for those using your module.
And in order to make it convenient for you, use code editors with the ability to automate such routine actions.


Answer 4

Threw in a class that allows you to solve your problem. If you like it and do not understand it, then tomorrow I will comment on my code. All data is hidden and a minimum of setters and getters (one for each data type).

# include & lt; iostream & gt;
#include & lt; string & gt;
using namespace std;
class Test {
private:
  class VarInt {
  public:
    int a;
    int b;
  } i;
  class VarChar {
  public:
    char a;
    char b;
  } c;
public:
  void setInt (string var, int val) {
    if (var == "a")
      cout & lt; & lt; "a =" & lt; & lt; (i.a = val) & lt; & lt; endl;
    if (var == "b")
      cout & lt; & lt; "b =" & lt; & lt; (i.b = val) & lt; & lt; endl;
    if ((var! = "a") & amp; & amp; (var! = "b"))
      cout & lt; & lt; "error" & lt; & lt; endl;
  }
  int getInt (string var) {
    if (var == "a")
return i.a;
    if (var == "b")
      return i.b;
  }
  void setChar (string var, char val) {
    if (var == "a")
      cout & lt; & lt; "a =" & lt; & lt; (c.a = val) & lt; & lt; endl;
    if (var == "b")
      cout & lt; & lt; "b =" & lt; & lt; (c.b = val) & lt; & lt; endl;
    if ((var! = "a") & amp; & amp; (var! = "b"))
      cout & lt; & lt; "error" & lt; & lt; endl;
  }
  char getChar (string var) {
    if (var == "a")
      return c.a;
    if (var == "b")
      return c.b;
  }
};
int main (int argc, char * argv []) {
  Test t;
  t.setInt ("a", 10);
  t.setInt ("b", 20);
  t.setInt ("x", 30);
  cout & lt; & lt; t.getInt ("b") & lt; & lt; endl;
  t.setChar ("a", '+');
  t.setChar ("b", '-');
  t.setChar ("x", '~');
  cout & lt; & lt; t.getChar ("b") & lt; & lt; endl;
  return 0;
}

output:

 enter image description here

Programmers, Start Your Engines!

Why spend time searching for the correct question and then entering your answer when you can find it in a second? That's what CompuTicket is all about! Here you'll find thousands of questions and answers from hundreds of computer languages.

Recent questions