Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using "Static" Keyword to Limit Access in C++ Member Functions

I understand that one benefit of having static member functions is not having to initialize a class to use them. It seems to me that another advantage of them might be not having direct access to the class's not-static stuff.

For example a common practice is if you know that a function will have arguments that are not to be changed, to simply mark these constant. e.g.:

bool My_Class::do_stuff(const int not_to_be_changed_1,
                        std::vector<int> const * const not_to_be_changed_2)
{
  //I can't change my int var, my vector pointer, or the ints inside it.
}

So is it valid to use static member functions to limit access. For example, lets say you have a function

void My_Class::print_error(const unsigned int error_no) {
  switch (error_no) {
    case 1:
      std::cout << "Bad read on..." << std::endl;
      break;
    //...
    default:
      break;
  }
}

Well here we're not going to be accessing any member variables of the class. So if I changed the function to:

static void My_Class::print_error(const unsigned int error_no) {
  switch (error_no) {
    case 1:
      std::cout << "Bad read on..." << std::endl;
      break;
    //...
    default:
      break;
  }
}

I'd now get an error, if I inadvertently tried to access one of my private var, etc. (unless I pass myself an instance of my class, which would be purposeful ^_^ !)

Is this a valid technique, similar to proactively making args that should not be changed constants?

What downsides might it have in terms of efficiency or use?

My chief reason for asking is that most of the "static" tutorials I read made no mention of using it in this way, so I was wondering if there was a good reason why not to, considering it seems like a useful tool.


Edit 1: A further logical justification of this use:

I have a function print_error,as outlined above. I could use a namespace:

namespace MY_SPACE {
   static void print_error(...) {
      ...
   } 

   class My_Class {
      ....
      void a(void)
   }
}

But this is a pain, because I now have to lengthen ALL of my var declarations, i.e.

MY_SPACE::My_Class class_1;

all to remove a function from my class, that essentially is a member of my class.

Of course there's multiple levels of access control for functions:

//can't change pointer to list directly
void My_Class::print_error(std::vector<int> const * error_code_list) {...}

//can't change pointer to list or list members directly
void My_Class::print_error(std::vector<int> const * const error_code_list) {...}

//can't change pointer to list or list members directly, access
//non-const member vars/functions
void My_Class::print_error(std::vector<int> const * const error_code_list) const {...}

//can't change pointer to list or list members directly, access
//non-static member vars/functions
static void My_Class::print_error(std::vector<int> const * const error_code_list) {...}

//can't change pointer to list or list members directly, access
//member vars/functions that are not BOTH static and const
static void My_Class::print_error(std::vector<int> const * const error_code_list) const {...}

Sure this is a bit atypical, but to lessening degrees so are using const functions and const variables. I've seen lots of examples where people could have used a const function, but didn't. Yet some people think its a good idea. I know a lot of beginning c++ programmers who wouldn't understand the implications of a const function or a static one. Likewise a lot would understand both.

So why are some people so adamantly against using this as an access control mechanism if the language/spec provides for it to be used as such, just as it does with const functions, etc.?

like image 943
Jason R. Mick Avatar asked Oct 05 '10 19:10

Jason R. Mick


People also ask

What are the restrictions on the use of static member functions?

You cannot have static and nonstatic member functions with the same names and the same number and type of arguments. Like static data members, you may access a static member function f() of a class A without using an object of class A .

Can a static member function access member variable of an object?

A static member function cannot access non-static member variable.

What does the static keyword do in C?

A static function in C is a function that has a scope that is limited to its object file. This means that the static function is only visible in its object file. A function can be declared as static function by placing the static keyword before the function name.

Can static member function private?

Making a function a static member of a class rather than a free function gives two advantages: It gives the function access to private and protected members of any object of the class, if the object is static or is passed to the function; It associates the function with the class in a similar way to a namespace.


4 Answers

Any member function should have access to the other members of the object. Why are you trying to protect yourself from yourself?

Static members are generally used sparingly, factory methods for example. You'll be creating a situation that makes the next person to work with your code go "WTF???"

like image 60
Mark Ransom Avatar answered Oct 11 '22 22:10

Mark Ransom


Don't do this. Using static as an access-control mechanism is a barbaric abomination.

One reason not to do this is because it's odd. Maintenance programmers will have a hard time understanding your code because it's so odd. Maintainable code is good code. Everybody gets const methods. Nobody gets static-as-const. The best documentation for your code is the code itself. Self-documenting code is a goal you should aspire to. Not so that you don't have to write comments, but so that they won't have to read them. Because you know they're not going to anyway.

Another reason not to do this is because you never know what the future will bring. Your print_error method above does not need to access the class' state -- now. But I can see how it one day might need to. Suppose your class is a wrapper around a UDP socket. Sometime in the middle of the session, the other end slams the door. You want to know why. The last messages you sent or received might hold a clue. Shouldn't you dump it? You need state for that.

A false reason to do this is because it provides member access control. Yes it does this, but there are already mechanisms for this. Suppose you're writing a function that you want to be sure doesn't change the state of the object. For instance, print_error shouldn't change any of the object's state. So make the method const:

class MyClass
{
public:
  void print_error(const unsigned int error_no) const;
};

...

void MyClass::print_error(const unsigned int error_no) const
{
  // do stuff
}

print_error is a const method, meaning effectively that the this pointer is const. You can't change any non-mutable members, and you can't call any non-const methods. Isn't this really what you want?

like image 38
John Dibling Avatar answered Oct 11 '22 22:10

John Dibling


Static member functions should be used when they are relevant to the class but do not operate on an instance of the class.

Examples include a class of utility methods, all of which are static because you never need an actual instance of the utility class itself.

Another example is a class that uses static helper functions, and those functions are useful enough for other functions outside the class.

like image 1
David R Tribble Avatar answered Oct 11 '22 21:10

David R Tribble


It is certainly fair to say that global scope functions, static member functions, and friend functions aren't quite orthogonal to one another. To a certain extent, this is largely because they are intended to have somewhat different semantic meaning to the programmer, even though they produce similar output.

In particular, the only difference between a static member method and a friend function is that the namespaces are different, the static member has a namespace of ::className::methodName and the friend function is just ::friendFunctionName. They both operate in the same way.

Well, actually there is one other difference, static methods can be accessed via pointer indirection, which can be useful in the case of polymorphic classes.

So the question is, does the function belong as "part" of the class? if so, use a static method. if not, put the method in the global scope, and make it a friend if it might need access to the private member variables (or don't if it doesn't)

like image 1
SingleNegationElimination Avatar answered Oct 11 '22 21:10

SingleNegationElimination