3

A static variable in a member function is a class level variable, meaning that all class instances access the same variable.

class foo{
 int doingSomething(){
   static int count =0;
   static int someValue=0
   count++;
   if(count%10 == 0){
     someValue *= counter;
     }
   someValue += counter;
   return someValue * 2;
 }
}

I want a way to count the number of times count() was called in each instance of foo separately, i can do this :

class foo{
 int count;
 int someValue;
 int doingSomething(){
   count++;
   if(count%10 == 0){
     someValue *= counter;
 }
 someValue += counter;
 return someValue * 2;
}

but my problem with this approach is that count and somevalue is only used and accessed in foo by doingSomething(), so there is no reason for it to be a member variable, since it opens the door to it modified and used by other class member function, and i want to prevent that. is there a solution that i am missing ?


EDIT 1: The idea is to count the number of time that doingSomething() was called in each instance of Foo, and this value will be used only by 'doingSomething()' to compute other values, which will be different for each instance.

Why? doingSomething() compute a int someVariable the first time is called, then stores it for later use, this stored value is used by doingSomthing() 10 times with every call, every 11calls int someVariable is recalculates and this new value is used...process repeated indefinitely.

0

5 Answers 5

4

you can hide your counter in a base class

class base_foo
{
public: 
 void doSomething()
 {
     counter++;
     //other fun stuff
 }

private:
   int counter;
};

class foo : base_foo
{
public:
    foo()
    {
        doSomething();
    }
// your other code
};
Sign up to request clarification or add additional context in comments.

4 Comments

The base class is still accessible equally to any member function of Foo
@BinaryA you could place doingSomething() in the base class and use public inheritace. private: int counter; will be inaccessible.
@DaBrain another great idea, if RedOctober wants to update his answer with your idea, it would upvoted
@BinaryA I would have to disagree. Even as is, int counter is a private member variable of the base class and therefore is not directly accessible from foo.
3

One way I could see you doing this is with a std::map. You could have a static std::map<class_name*, int> in the function and every time the function is called use operator[] with this and increment the int part.

class Foo
{
public:
    void bar()
    {
        static std::map<Foo*, int> counter;
        counter[this]++;
    }
};

3 Comments

Very cool idea, if a new function was to be declared in Foo would this new function be able to access counter?
@BinaryA No as counter is local to bar()
@BinaryA what do you mean by filling counter? counter[this]++; already fills counter every time the function is called. Did you want to see a use case?
3

C++, like many other languages, doesn't have a way that multiple functions can share a variable without allowing all functions access (besides putting them into a class together, which you already know). There are some ways to approximate what you want, however.

Here's a simple fix:

class foo
{
public:
  int count () 
  {
    static int count_ = 0;
    return ++count_; 
  }
};

Now only foo::count can access it, and it does double duty: increments it, and returns it.

If you don't like that, here's a lengthier fix that matches the desired behavior:

class foo
{
private:
  class Counter //hides all that counting stuff
  {
  public:  
     //ctor initializing count...
  private:      //it's all hidden!  Only friends can access
    friend int  foo::returnCount () const; 
    friend void foo::updateCount ();

    int count () const { return count_; }
    void updateCount (){ ++count_; }

    int count_;
  };

public:
                  //and only these two functions are friends.
  int returnCount () const { return myCounter_.count (); }
  void doSomethingAndIncCount()       { myCounter_.updateCount ();   }

private:
  static Counter myCounter_;
};

So keeping all the contents of Counter private means nobody can access... except the functions you picked out, and designated as friends of Counter.

That's an awful lot of mess to go to, though. I'd go with the first solution, or else not worry about those other member functions accessing count.

4 Comments

"C++, like other languages" in JS you can something like that with closures.
The first simple fix with static int count_; is missing an initialization.
Actually the second example is missing the initialization too.
Fixed that now. Thanks.
0

I don't think there are options in C++ to have method scope private field. Encapsulation rules are that class is the unit of encapsulation so you should know what to do and what not to do within your own class.

You can achieve similar effect by using separate functor:

#include <iostream>
using namespace std;

class Counter {
    private:
     int counter = 0;
    public:
     int operator () () {
        return counter++;
     }
};

class Test {
    public:
     Counter count;
};

int main() {
    Test test;
    test.count();
    test.count();
    std::cout << test.count();
    return 0;
}

In this case counter is completely inaccessible from class Test.

3 Comments

The problem is that count() can be still called by any member of 'class Test'
@BinaryA and how is that a problem? If you want to go that far then move all your dosomething logic to Counter class (and call it SomethingDoer). But honestly what you are trying to achieve doesn't make much sense.
My issues is that in my second code snippet, i have 2 class variables that are only used in one function, it is not a big deal, but i would rather isolate it from the rest of the class.
0

Is this what you are trying to achieve:

#include <iostream>
#include <string>

using namespace std;

class Foo
{
private:
    int counter;

public:

    Foo() : counter(0) {};

    void count()
    {
        counter++;
    }

    int getCounter()
    {
        return counter;
    }
};

int main()
{
    Foo foo1;
    Foo foo2;

    foo1.count(); foo1.count(); foo1.count();
    cout << "You called count() from foo1 " << foo1.getCounter() << " times" << endl;

    foo2.count();
    cout << "You called count() from foo2 " << foo2.getCounter() << " times" << endl;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.