Declaring static helper methods in a class



  • I presume that like me you find yourself writing convenience "helper" methods inside a class, to do something like perform a calculation, where the method does not access this or any instance member variables/methods.

    Presumably because I have been sinful in a previous reincarnation, I have to do my Qt work in Python instead of C++. In Python when a member function does not access self (i.e. this) my IDE gives it a "wiggly underline", warning that "method may be static". To get rid of that I have to place a "decorator" line above it to read @staticmethod, whereupon it takes away self and is happy. Being a grumpy sort this tends to irritate me.

    • When you do the same in C++ would the compiler you use warn you about the method could be static?
    • Do you always bother to insert static in the method declaration?

    Let's say the method is private so you're only going to use it from within the class, you don't have to think about the outside world. BTW, Python has the same semantics as C++ for calling static methods where you can either use theClass::method() or [this->]method().


  • Qt Champions 2018

    @JonB said in Declaring static helper methods in a class:

    When you do the same in C++ would the compiler you use warn you about the method could be static?

    Not the compiler, this is more a "static analysis" warning

    Do you always bother to insert static in the method declaration?

    It's good practice if you don't want the method to use this to declare it static, yes


  • Qt Champions 2017

    @JonB said in Declaring static helper methods in a class:

    Presumably because I have been sinful in a previous reincarnation, I have to do my Qt work in Python instead of C++.

    You must've really been monstrous in that previous incarnation ... ;)

    • When you do the same in C++ would the compiler you use warn you about the method could be static?

    Not in my experience. The compiler isn't that smart, and honestly I don't see why it should be ...

    • Do you always bother to insert static in the method declaration?

    I don't due to a couple of reasons. C++, being a compiled language where you have sources and headers, you can hide the implementation without exposing it through the class' interface. So there are a couple of distinct cases:

    1. You use private classes, then you have the method in the private class and it does not pollute your public class' interface.
    2. You don't use the class' internals, then you can have it as a local function that's not exported from the binary. Then any global function in the source will do as long as you hide it behind an anonymous namespace or declare static linkage (or use Q_DECL_HIDDEN).
    3. You don't fall in 1) or 2). Then your question is relevant and as @VRonin said it's good idea to have it as static, mostly because you ensure this is not "injected". This has implications if you want to use it as a callback for example. If a method you'd have:
    return_type (ClassName::*)(ArgumentType argument, ...) cv_qualifier;
    

    as a prototype, otherwise, being static you'd have notably:

    return_type (*)(ArgumentType argument, ...);
    

    The former isn't directly usable as a function pointer/functor. You'd need to bind it to an object to call and use, the latter doesn't suffer from that limitation.

    BTW, Python has the same semantics as C++ for calling static methods where you can either use theClass::method() or [this->]method().

    this->method() can be really misleading in C++, provided you have (wrong) expectations about type resolution. If you have a static with the same name in a derived and a base class, and you use object->method() with object being a base pointer, it's going to call you the base class' static.



  • @kshegunov said in Declaring static helper methods in a class:

    Not in my experience. The compiler isn't that smart, and honestly I don't see why it should be ...

    Trouble is, Python/PyCharm thinks it is/should be that smart! I try to keep the "wiggly underline" warnings down to a minimum, as it's so fond of them that they are all over my code, and one wants to distinguish the important ones from the insignificant ones.

    I am talking about really simple helper methods, nothing like "callback"s or anything like that. Methods which do not need to know anything about the class/instance. For the sake of argument, think of a method which just returns the square of some int it is passed, and happens to be useful throughout my class.

    In C++ I don't mind too much having to write:

    static int MyClass::square(int num)
    ...
    

    using the static dotted around the methods in the class as appropriate. It retains the function declaration on one line. In Python I have to edit from:

    def square(self, num)
    ...
    

    to:

    @staticmethod
    def square(num)
    ...
    

    Personally I don't like that e.g. when you fold down all your class's functions that makes these occupy two lines instead of one. Halves the overview I can fit on my screen!

    Anyway, you guys have indicated that C++ compilers don't tend to nag about whether a function does or does not access members....


  • Moderators

    @JonB said in Declaring static helper methods in a class:

    Personally I don't like that e.g. when you fold down all your class's functions that makes these occupy two lines instead of one. Halves the overview I can fit on my screen!

    Do you program on a 2000 Smartphone screen ? ;-)

    Jokes aside, are you sure that the warning is actually due to the Python-interpreter and not coming from your IDE.
    If the later, there may be an option to deactivate it.


  • Qt Champions 2017

    @JonB said in Declaring static helper methods in a class:

    For the sake of argument, think of a method which just returns the square of some int it is passed, and happens to be useful throughout my class.
    In C++ I don't mind too much having to write:
    static int MyClass::square(int num)

    This falls under 2) from my previous post:

    namespace  {
        inline int square(int arg)
        {
             // ...
        }
    }
    

    Voila, no statics and it's hidden. Now I feel for you, but I have no clue what Python does or does not, so I'm of little help. @J-Hilk is right though, it might come from the IDE itself, so it may provide a way to turn it off.



  • @J.Hilk

    Do you program on a 2000 Smartphone screen ? ;-)

    No, that is unfair! With each method having a blank line above it, when folded each one occupies two lines. That fits maybe 20, if that, on a visible page. Putting in the @staticmethod occupies an extra line, reducing the overview I can see by 50%. Do you want me to be productive or not? :)

    The warnings shown by the IDE are dictated by Python "PEP"s, so in a sense they are to do with the language definition not just what the IDE feels like. I probably could disable the individual one (if I could find it, there are hundreds!) in the IDE preferences. I try not to do that, I like to know what Python thinks I ought to know as it's all a minefield. So I just wanted to know what you C++-ers saw/did about this issue.

    @kshegunov
    Horrible! In the middle of the various functions you have in your class, dotted around you suddenly have namespace { ... } surrounding the odd method. It may be "correct", but I cannot believe when you fold down your code to see all the methods in the class this can look anything but a mess....!


  • Qt Champions 2017

    Doesn't it allow you to pull this tag on the same line, though? Like:

    @staticmethod def square(num)
    

    or

    def square(num) @staticmethod
    

    or something akin?

    Horrible! In the middle of the various functions you have in your class, dotted around you suddenly have namespace { ... } surrounding the odd method. It may be "correct", but I cannot believe when you fold down your code to see all the methods in the class this can look anything but a mess....!

    That goes in the source file, on top. It has nothing to do with the actual class. :)

    Example:
    myclass.h

    class MyClass
    {
    public:
         int method();
    };
    

    myclass.cpp

    namespace
    {
        int square(int x)
        {
             return 0;
        }
    }
    
    int MyClass::method()
    {
         return square(55);
    }


  • @kshegunov

    Doesn't it allow you to pull this tag on the same line, though?

    Lol. Python is fundamentally "line aware", unlike a respectable language.

    • One decorator per line (makes it clearer to read, write and change order of decorators)
    • Separate from the def syntax (desired by some for making decoration stand out and keeping def the same)
    • All decorators line up in one column immediately above the function name (easy to browse and see what's going on).

    OK, I get how you use the "anonymous" namespace here. Now your solution cannot access, say, a type/constant (not member) you have declared inside the class. I want the function to live inside the class like everything else. I was, as you know, just asking whether you/the compiler insist you use static against a member function which does not happen to access this.


  • Qt Champions 2017

    @JonB said in Declaring static helper methods in a class:

    unlike a respectable language.

    I'm beginning to understand ... that's ultimately stupid. Like if it changed my sentence if I'd put two spaces instead of one ...
    A smart decision by the language designers for sure.


  • Moderators

    @kshegunov
    I fought with pyhton for about 1 semester, we used Panda3D for Near-field scanning visualization.

    I've avoided it at any chance since than, but it forced me into cleaner code writing and installed the beginning stages of OCD in my mind ;-)

    so it has it uses...


  • Qt Champions 2017

    @J.Hilk said in Declaring static helper methods in a class:

    but it forced me into cleaner code writing and installed the beginning stages of OCD in my mind ;-)

    C did that for me by means of segfaulting. Makes you rethink your approach to indentation and styling, beside other things (like sanitation) ...

    so it has it uses...

    Maybe. They say my beloved fortran has its uses, but then again I haven't found any of them. Maybe it's just my TV that's broken ...



  • @kshegunov
    C does not segfault. Programmers write code which segfaults!

    Are you saying you have written TV-interface-code in FORTRAN?!


  • Qt Champions 2017

    @JonB said in Declaring static helper methods in a class:

    C does not segfault. Programmers write code which segfaults!

    That's what I meant, yes.

    Are you saying you have written TV-interface-code in FORTRAN?!

    Oh, don't get me started ...


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.