简体   繁体   中英

Separate static variable inside class member function among instances

MyClass::Foo()
{
  static bool isFirst = true;
  if (isFirst)
    do something;
  isFirst = false;
}

MyClass::Bar()
{
  static bool isFirst = true;
  if (isFirst)
   do something;
  isFirst = false;
}

I have used the above structure and it worked well so far when I worked with only one instance of the class.
The problem is all instances of MyClass seem to share the static variable.

How can I make the variable not-shared by different instances(but shared among same instance)?

Do I need to maintain a separate data structure to store instances somewhere?
Or could this be done with clever use of c++ syntax?

edit

I forgot to mention I have such variables in many functions.
Added MyClass::Bar() up there.
I hope there's a way without defining isFirstForFoo, isFirstForBar, and so on as class member variables, because there are so many.

My actual code looks like this

BookInfoVector_t DBProcess_GET_BOOK::SelectBookList()
{   
    const char* query = "some query statement";

    static nsl::SQLitePreparedStatement preparedStatement = nsl::SQLitePreparedStatement(static_cast<nsl::SQLiteConnection*>(mDBConnection), query);
    static bool isFirst = true;
    _InitializeDBProcess(&preparedStatement, isFirst);
...
}

I do some initialization on preparedStatement on first run of code, and as you can imagine, I have to define isFirst for all queries I use.

In your MyClass.h file:

class MyClass {
public:
  MyClass();
  void Foo();

private:
  bool isFirst;
}

In your constructor:

MyClass::MyClass() {
  isFirst = true;
}

In your method:

void MyClass::Foo()
{
  if (isFirst)
    do something;
  isFirst = false;
}

You may want to rename isFirst now to something like mIsFirst or isFirst_ or whatever your style guide recommends for member variables, since you have now made it an instance member.

You may also wish to use an initializer list in the constructor, instead of doing it in the body of constructor.

The above left as an exercise for the reader.

The problem is all instances of MyClass seem to share the static variable.

That is exactly what a static variable is.

How can I make the variable not-shared by different instances(but shared among same instance)?

You need to make isFirst a (non- static ) member of MyClass . And rename it, following your edit:

class MyClass
{
public:
    MyClass();
    void Foo();
    void Bar();
private:
    bool should_foo;
    bool should_bar;
};

MyClass::MyClass()
    :should_foo(true)
    ,should_bar(true)
{
}

void MyClass::Foo()
{
    if (should_foo)
    {
        // do something;
        should_foo = false;
    }
}

void MyClass::Bar()
{
    if (should_bar)
    {
        // do something;
        should_bar = false;
    }
}

If you really "have such variables in many functions", then I recommend you rethink the design of MyClass . I can't tell you how, given how vague and generic your example is but you're almost certainly violating the Single Responsibility Principle .

Use an instance variable in the class. The various member functions of a single class are expected to be tightly coupled, and not stomp on each other's data.

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