简体   繁体   中英

static vs const member functions

I find it difficult to decide when to use private static member functions and when to use private const member functions.

Let's say we have a method DoSomething() that needs to check if one or more members is something:

class Foo
{
public:
    void DoSomething()
    {
         // if(IsASomething()) ...
         // or
         // if(IsSomething(a_)) ...
private:

    int* a_;
    int* b_;

    static bool IsSomething(int* n) {return n != null;}

    bool IsASomething() const { return a_ != null;}
    bool IsBSomething() const{ return b_ != null;}
};

When a helper function will only be used in one way (say only to check if a_ is something), i tend to go with a const member function. If it will be used with several parameters, I tend to stick with the static version. Are there other factors that I haven't thought of would persuade me to choose differently?

Edit: I think I explained myself poorly, so I added definitions to the example.

  1. static functions cannot use any non-static member functions or variables.

  2. static functions cannot be overridden polymorphically.

  3. You can take an address of a static function.

  4. You don't need an instance of your class to call a static function.

  5. A member function marked const , can access class members, call other const functions, and be overridden polymorphically if marked virtual .

const after the function means "this function does not modify any class members [except those marked mutable ].

static means "this function does not have a hidden this pointer passed to the function", so is really just like any free function that isn't part of the class, except it's kind of "namespaced" inside the class.

They are completely and utterly different "animals".

Edit: It really comes down to what makes most sense for the class/system design. It is typically right to use static functions for things that are not actually part of the class as such. I very rarely use static functions, since they make little sense except in some very special circumstances - the question to ask here is, "if I make this static, why is it part of this class at all?", and if the answer is "because it belongs on the class as it ", then it should be a static function. On the other hand, if the answer isn't a solid reason, then it probably doesn't belong in the class and should end up as static free functions (perhaps in an anononymous namespace) in the source file, rather than in a class.

In my compiler project (a total of around 13,000 lines of C++ code), I have:

  • One static member function (to translate a string into a keyword token in the token class - because it's called during the construction of the token itself, and thus isn't suitable as a member-function).
  • Around 50 static functions inside .cpp files that are not member functions. These do things like:
    • IsConstant() for some expression
      • No, I don't want that as a member function of the expression itself, as that is a generic class that can express lots of things, which would mean that I'd have to have a few dozen return false implementations of a virtual function, for a relatively rare case]
    • Error functions (printing an error message)
    • One could make them static members, but users of the class don't need to use these functions, which means that exposing them to the outside is pretty pointless.

I tend to use free functions in unnamed namespace when possible.

So between

// header

class A
{
public:
    bool HasCustomProperty() const();
private:
    bool IsOdd() const;
    bool IsHappy() const;
private:
    int a;
};

// cpp

bool A::HasCustomProperty() const
{
    return IsOdd() && IsHappy();
}

and

// header

class A
{
public:
    bool HasCustomProperty() const();
private:
    static bool IsOdd(int n);
    static bool IsHappy(int n);
private:
    int a;
};

// cpp

bool A::HasCustomProperty() const
{
    return IsOdd(a) && IsHappy(a);
}

and

// header

class A
{
public:
    bool HasCustomProperty() const();
private:
    int a;
};

// cpp
namespace {
    bool IsOdd(int n);
    bool IsHappy(int n);
}

bool A::HasCustomProperty() const
{
    return IsOdd(a) && IsHappy(a);
}

I choose the last one.

They are two different things and are not alternates:

const member functions are not allowed to modify class instant data. static member functions do not have an associated class instance.

Using OP's example class definintion then in inplementstion ...

bool Foo::IsSomething(int* n)
{
   return *n < *a_; // not ok. static method has no this    
}


bool Foo::IsASomething() const
{
   return (*a_ > 8) // ok as member a_ not changed
}

bool Foo::IsASomething() const
{
    *a_ +=4;   // not ok as a_ cannot be changed by const member
    return (*a_ > 8);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM