Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Is there an easy way to create getters and setters for ALL variables in a .h file?



  • I'm new to Qt and Qt Creator, and I really like it.

    I like the automatic generation of getters and setters for variables declared in a .h file. However, I find it tedious to right-click on each variable, select 'Refactor' and then click to add getters and setters. I then have to jump back to the .h file (as I am automatically switched to the .cpp file) and do the same for the next variable.

    Is there any way to create getters and setters for all private variables in a .h file?


  • Moderators

    Yeah, it is kinda annoying, but I don't think there's a way to do that.

    You can speed it up a little with keyboard: place the cursor on variable, alt+Enter to show quick fix menu, select the option you want with arrows, hit Enter and, when it generates the members, hit F4 to go back to the header, down arrow to go to next variable and so on. Still tedious but a lot faster than with mouse.


  • Lifetime Qt Champion

    @Kiwi-NFL-Fan said in Is there an easy way to create getters and setters for ALL variables in a .h file?:

    Is there any way to create getters and setters for all private variables in a .h file?

    Why do you make them private then when you allow public access to all anyway?



  • @Christian-Ehrlicher said in Is there an easy way to create getters and setters for ALL variables in a .h file?:

    @Kiwi-NFL-Fan said in Is there an easy way to create getters and setters for ALL variables in a .h file?:

    Is there any way to create getters and setters for all private variables in a .h file?

    Why do you make them private then when you allow public access to all anyway?

    What do you mean? I thought that people are suppose to make Getter and Setter functions and make member variables as private.
    Even Qt libraries are designed like that.


  • Lifetime Qt Champion

    @stretchthebits
    Hi
    well it been debated over the years
    https://softwareengineering.stackexchange.com/questions/314783/why-are-getter-and-setter-functions-considered-to-be-against-oo-design-why-they

    In any case, if not misused they provide a way to handle sanity checks in one place and makes it far easier to have mockup objects
    and besides like in Qt it's a perfect place to call update when value changes.

    After 30 years of also maintaining old code, i can say it's a mess waiting to happen to allow public access directly to the variables. :)
    ( depending on the scale of the app ofc and the new class of IDE allowing true refactoring also helps.)


  • Lifetime Qt Champion

    @stretchthebits said in Is there an easy way to create getters and setters for ALL variables in a .h file?:

    I thought that people are suppose to make Getter and Setter functions and make member variables as private.
    Even Qt libraries are designed like that.

    No, Qt does not simply make all it's private variables public as you wanted :)



  • @mrjj said in Is there an easy way to create getters and setters for ALL variables in a .h file?:

    @stretchthebits
    Hi
    well it been debated over the years
    https://softwareengineering.stackexchange.com/questions/314783/why-are-getter-and-setter-functions-considered-to-be-against-oo-design-why-they

    In any case, if not misused they provide a way to handle sanity checks in one place and makes it far easier to have mockup objects
    and besides like in Qt it's a perfect place to call update when value changes.

    After 30 years of also maintaining old code, i can say it's a mess waiting to happen to allow public access directly to the variables. :)
    ( depending on the scale of the app ofc and the new class of IDE allowing true refactoring also helps.)

    OK. I thought it was the cornerstone of OOP.
    Personally, I am more of the procedural type of person. I use C++ but I do have some free functions. I have never been comfortable with Java.
    I think there were some limitations I ran into. I think I could not pass a variable as a reference or was it pass a variable as a pointer

    void MyFunction(int &variable)
    or
    void MyFunction(int *pvariable)

    and I think I could not copy an address
    int64 IWantAdress = (int64) &variable;

    and some parts of my code might be in inline assembly and in Java, you can’t use specific CPU features.

    In my personal projects, I never write Getters. I only write Setters and nearly all member variables are public.
    I think a lot of OOP people would be upset with me :)



  • @Christian-Ehrlicher said in Is there an easy way to create getters and setters for ALL variables in a .h file?:

    No, Qt does not simply make all it's private variables public as you wanted :)

    I guess there are some things that the Qt libs would want to keep internal and they never provide any Getters and Setters as part of the API.



  • @stretchthebits said in Is there an easy way to create getters and setters for ALL variables in a .h file?:

    What do you mean? I thought that people are suppose to make Getter and Setter functions and make member variables as private.
    Even Qt libraries are designed like that.

    Doing it blindly is definitely an antipattern. If your getters and setters don't do anything in particular (such that they can be generated by a tool), then they are just overhead. They make the code longer larger and slower. Hiding private variables is only important if there aren't a part of the public interface of a class.

    If you eventually change your mind, you can always use refactoring tools to go from direct variable access to getters and setters for a certain variable. But you should think carefully about what the public interface of a class should actually look like. And think carefully about what private variables are actually hiding, and whether they are actually being hidden in any useful sense.



  • C++ is not an OO language. It is a multiparadigm language which also includes OOP. This allows us to rethink a few things about what good code should look like. However, OOP is constructed and designed by OO purist. They will tell you that everything which does not look the way they want it to be is wrong.

    If you start to separate the idea of OO and its implementation, then OO only knows about sending messages. C++ and Java implement "sending messages" as calling methods. So, if you stick to the pure idea of OO you have to use getters and setters to access the current state of an object.

    Furthermore, another idea of OO is that you do not show any of your implementation details. This would prevent you from changing the implementation in the future. Note, that in pure OO all methods have to be virtual (like in Java) as well, so that any method can be overridden. One example for this I remember from my CS lectures is the complex number class. In a first attempt anybody would implement a complex number class with two data members: the real part and the imaginary part. Using Euler's formula one can also write complex numbers as radius and angle. Certain operations are faster in this representation. So, one might later change their mind about the implementation and change from the carthesian representation to polar coordinates. If you have used getters and setters changing the implementation is easy (for pure OO you should also use getters/setters within the class itself; using getters/setters is the only way in your entire code to access member variables). You just have to reimplement the accessor methods to use the new member variables. This is (some) of the reasoning behind pure OO.

    That being said: I am personally advocating to making you member variables public instead of implementing both getters and setters. Publicly read-only members, however, need getters only to hide write access. Sometimes it might make for a cleaner and more consistent interface to hide all members (instead of just publicly read-only members) behind getters and setters. Bjarne Stroustrup (the inventor of C++) also advocates (or at least once did) to make members public in these scenarios. If you later change your mind (like in my complex class example) you can still hide the implementation behind a property class. In this context a property class is a class that implements a conversion operator T() as getter and operator= as setter.


  • Moderators

    @stretchthebits said in Is there an easy way to create getters and setters for ALL variables in a .h file?:

    I guess there are some things that the Qt libs would want to keep internal and they never provide any Getters and Setters as part of the API.

    The thing that Qt keeps private is the object state. Which the fellows above gladly spill over the place by advocating just having public members. The main point of OOP is to encapsulate the object state and hide any internal details behind a wall. Whenever you declare a member public your class interface is stuck with it (and its type) for a long, long time. Changing the member from int to say float wreaks havoc on your API (the class interface) - it suddenly changes it for all consumers, and then as usual all your users are getting their pitchforks and are preparing for a good ol' public lynching.
    To add insult to injury, member variables are an implementation detail, what happens when you have say an UI class that has put a public member for the value and a min/max boundary. How do you enforce the constraint if you don't and can't manage the state change? What if tomorrow you drop the member variables all together and put the data in some remote location (say a file) and retrieve it directly, do you break the interface for your users?

    @wrosecrans said in Is there an easy way to create getters and setters for ALL variables in a .h file?:

    They make the code longer larger and slower.

    That's simply not true. The presence of a method can make code slower at the binary image boundary (i.e. PIC and stubs), and even then in 99.999% of cases it's simply irrelevant for all practical purposes.

    @SimonSchroeder said in Is there an easy way to create getters and setters for ALL variables in a .h file?:

    This would prevent you from changing the implementation in the future.

    This would allow you to change the implementation in the future.

    Note, that in pure OO all methods have to be virtual (like in Java) as well, so that any method can be overridden.

    Not true. Firstly what does "pure OO" mean? virtual is a detail that's necessary to facilitate OO, but it certainly isn't a requirement to allow every method to be overriden. What would be the point of that to begin with? Java (and C++) have final specifically to prevent the user from doing that in some cases, you don't suppose that's a random whim, do you?

    In this context a property class is a class that implements a conversion operator T() as getter and operator= as setter.

    This is simply abusing the idea of OOP. The idea of the setters and getters are to expose an interface to a part of the state of the object, while the state may be very complex. This supposed class for a property solves none of the issues the getters and setters stand to solve - i.e. not solving intertwined members (i.e. dependent on one another), nor does it solve the problem when the state is stored in a way different than a member variable.



  • @kshegunov, said in Is there an easy way to create getters and setters for ALL variables in a .h file?

    This would allow you to change the implementation in the future.

    You are correct. I simply had too many negations in my mind. That made my statement incorrect. What I meant was that not hiding implementation details prevents you from changing the implementation in the future.

    virtual is a detail that's necessary to facilitate OO, but it certainly isn't a requirement to allow every method to be overriden. What would be the point of that to begin with? Java (and C++) have final specifically to prevent the user from doing that in some cases

    From my understanding of the OOP idea (independent of the implementation) each object should decide what messages it responds to and how to handle that message. (All objects that respond to the same message with the same behaviour are of the same class. Using a class definition is an implementation detail of the OO idea and there are languages that use a different approach.) As long as you want to allow subclassing this would mean that all your public methods need to be virtual. If you make your class final you can certainly optimize for speed by dropping virtual. Though I never heard in the theory of OOP that there is such a thing as final. Still, I understand why OO languages have that feature.

    This supposed class for a property solves none of the issues the getters and setters stand to solve - i.e. not solving intertwined members (i.e. dependent on one another), nor does it solve the problem when the state is stored in a way different than a member variable.

    This depends on your definition of property. If you make the restriction for a property to mirror a member variable, you are right. In general, a property does not say how the state is stored. In those specific cases I would implement a specific inner class which uses the two operators to specifically mimic whatever you would write as a getter/setter in the outer class instead. I agree, that this is abusing the idea of OOP. On the other hand I am not the kind of guy that writes Java in C++ (i.e. to disregard the multiparadigm nature of C++). What I mean to say is that in C++ you could do it this way (if you made the wrong design decision at one point), not that you should.

    Q_PROPERTY itself is not so restrictive to always mirror a member variable. It does not – like I suggested – use operator T() and operator=, but uses property() and setProperty() instead. (Also, it uses a mapping from a string to its getters/setters.)


  • Moderators

    @SimonSchroeder said in Is there an easy way to create getters and setters for ALL variables in a .h file?:

    What I meant was that not hiding implementation details prevents you from changing the implementation in the future.

    Indeed, which is really the point of doing it to begin with.

    From my understanding of the OOP idea (independent of the implementation) each object should decide what messages it responds to and how to handle that message.

    That whole "messages" thing comes from Smalltalk (mostly), while you could consider it this way it's not as convenient. Let's settle on "methods represent bahaviour, properties represent state", does that sound good?

    Using a class definition is an implementation detail of the OO idea and there are languages that use a different approach.)

    OOP works with concepts, it doesn't know about defintions, declarations or classes. It has types (represented by classes in C++) and objects of some type (which is simply objects in C++).

    As long as you want to allow subclassing this would mean that all your public methods need to be virtual.

    Deriving a type has the main idea of extending the behaviours a type supports. This has nothing to do with virtual at all. As I said, virtual is an implementation detail in C++ to make available for the new types to change already existing behaviour. Nowhere does it say that anything must or should be virtual (i.e. overrideable/changeable). The fact that Java decided to give you only a hammer by no conceivable measure means every problem is a nail.

    If you make your class final you can certainly optimize for speed by dropping virtual. Though I never heard in the theory of OOP that there is such a thing as final. Still, I understand why OO languages have that feature.

    final has very little to do with "speed". Speed is not a subject in OOP at all. final has the main purpose of making a behaviour that was changeable into one that's not. That is to say (in c++ terms) - give the tool to the person designing an interface to allow/disallow changing a method's implementation (or the whole of the exposed interface).

    This depends on your definition of property. If you make the restriction for a property to mirror a member variable, you are right.

    Most certainly, but I never put any such restriction, quite the opposite.

    In general, a property does not say how the state is stored.

    Which is what I argued, I believe.

    In those specific cases I would implement a specific inner class which uses the two operators to specifically mimic whatever you would write as a getter/setter in the outer class instead.

    If and only if the specific part of the state is a separate type. Hence my argument that doing this blindly is simply abusing the idea of OOP. Think of it like this: you would rather generate a type only to provide read/write access to an int? This really makes no sense to me, the type is already available, you don't want to just proliferate types for no apparent reason.

    The counterargument goes: Say you're storing some sort of database identifier and this gets marshaled around your objects, then it does make sense to wrap this (integer usually) in a separate type to provide the constraints and validations. So however unbelievable programming requires thinking, it's not a bunch of patterns and rules that one stitches together in the frankencode of all code.
    <ot> This is the main reason I reacted on this thread.</ot>

    I agree, that this is abusing the idea of OOP. On the other hand I am not the kind of guy that writes Java in C++ (i.e. to disregard the multiparadigm nature of C++). What I mean to say is that in C++ you could do it this way (if you made the wrong design decision at one point), not that you should.

    The problem is that way you're not fixing the problem, you're alleviating the symptoms. The proper way of doing it is to refactor the interfaces and the implementations and bite the bullet when the clients of your code complain you've changed the interface. OOP isn't a cure for all things, most certainly, but the point is that whenever you have a big-sh system where you need to provide a long-term support for and relatively stable API for the users ... let's say it's been tried and tested to be an excellent tool for the job.

    You don't see much OOP in numbercrunching, yet you almost universally see only OOP in (business) logic parts of programs.

    Q_PROPERTY itself is not so restrictive to always mirror a member variable. It does not – like I suggested – use operator T() and operator=, but uses property() and setProperty() instead. (Also, it uses a mapping from a string to its getters/setters.)

    That's for runtime support. Q_PROPERTY is a detail of Qt's metatype/metaobject system, and you can give it any setter/getter to register for a given "property", it doesn't restrict you how you store, operate on, or implement the actual "property", that's up to you.


Log in to reply