3

Obviously non-static member function can read static data. In fact, that's an important point of having static data - so that instance member functions can read it.

But, is there a good reason (from a OOP design point of view) of having non-static member functions UPDATE the static data variable?

I know of the trivial example of how one might want to keep a counter of how many instances we've created of a particular object. So we can have the constructor update a static int counter. Like so

class Foo
{
    static int ctr;

    Foo()
    {
        ctr++;
    }
}

But other than this specific example, is there a good general reason of having non-static function update static variables?

Personally I think it seems a bit goofy, but I can't put my finger on what exactly is bothering me.

user3240688
  • 1,188
  • 3
  • 13
  • 34
  • Why should it be not allowed to update a static variable? If you really don't want to update it, why not make it `const`? – Colonel Thirty Two Sep 05 '14 at 03:07
  • What is the use case for having a static variable and then not updating it? Static variables in general should be pretty rare, but if you need one, you need it. – Ben Voigt Sep 05 '14 at 03:15
  • 'static' of static variable stands for 'static location(address) on the memery space, so only one substance exists on memory and that is shared among all instances of that class. In the nature of sharing, something has to have ablility to modify the static variable. Could you imagine that something other than intance members is most suitable for modifying the static variable? – Fumu 7 Sep 05 '14 at 04:40

2 Answers2

3

Sort of. You may have workers who are supposed to throw out tasks if they are duplicated, and you may do this by having a static set of in-process tasks to check against.

The problem with this sort of static use is it means you can only have one such class per... program. And what if the owner of the larger program wants to run this class twice? Oops. Or, what if another part of your program decides it really could use this task management system for something else? Oops. Any small program can become part of a large program to conserve threads and other resources (I'm especially used to a Java context where the JVM itself is very expensive).

So when you feel like you have a need for this pattern, try having an umbrella class to own the candidate static data as non-static data, and have one umbrella class instance for many sub instances. e.g.

class Worker {
    static set<WorkItem*> inProcess; // the old way of doing it
    void work(WorkItem* w) {
        inProcess.add(w);
}

Should become

class Worker {
    Manager* manager; // shared between all instances, until your program grows
    void work(WorkItem* w) {
        manager->accept(w);
    }
}

class Manager {
    set<WorkItem> inProcess;
    void accept(WorkItem* w) {
        inProcess.add(w);
    }
}

This problem applies to any static, non-constant data. But the problem becomes successively riskier as the data goes from read-only to read-write. Singleton is an anti-pattern.

Community
  • 1
  • 1
djechlin
  • 59,258
  • 35
  • 162
  • 290
  • Could the manager also register a `Worker` (such that each `Worker` is registered by exactly one `Manager`)? In that case it would be interesting to know how/when `Manager` registers `Worker`. How would you avoid leaking `this` of a partially constructed `Worker`? Would you protect the constructor and use a factory function for `Worker`? – Tobias Sep 05 '14 at 03:49
  • @Tobias that's a different design problem, but I would make manager responsible for creating worker if it's supposed to own it. manager.createWorker(...) will create a new worker then after it's created save it. – djechlin Sep 05 '14 at 03:56
0

From book

Thinking in C++, Volume 1, 2nd Edition, Bruce Eckel, President, MindView, Inc.

Static members in C++

There are times when you need a single storage space to be used by all objects of a class. In C, you would use a global variable, but this is not very safe. Global data can be modified by anyone, and its name can clash with other identical names in a large project. It would be ideal if the data could be stored as if it were global, but be hidden inside a class, and clearly associated with that class. This is accomplished with static data members inside a class. There is a single piece of storage for a static data member, regardless of how many objects of that class you create. All objects share the same static storage space for that data member, so it is a way for them to “communicate” with each other. But the static data belongs to the class; its name is scoped inside the class and it can be public, private, or protected.

Garland
  • 911
  • 7
  • 22
  • This is a good explanation, but I feel it's important to notice that static data inside a class is still the singleton antipattern, i.e. too global. – djechlin Sep 05 '14 at 03:48