Static member variable

For debugging, I would like to add some counter variables to my class. But it would be nice to do this without changing the header to cause a lot of recompilation.

If Ive correctly understood the keyword, the following two snippets would be exactly the same. Assuming, of course, that there is only one instance.

class FooA
{
public:
    FooA() : count(0) {}
    ~FooA() {}

    void update()
    {
        ++count;
    }

private:
    int count;
};

vs.

class FooB
{
public:
    FooB() {}
    ~FooB() {}

    void update()
    {
        static int count = 0;
        ++count;
    }
};

In FooA, you can get an account anywhere in the class, as well as inflate the title, since the variable must be deleted when it is no longer needed.

FooB , . . , , , FooB , .

  • ? , FooB, .
  • - , ?

: , , , , .

+3
4

. , . InterlockedIncrement().

+3

, , ++ - , . , , , , .

, , :

class Counters {
public:
  // Counters singleton request pattern.
  // Counters::get()["my-counter"]++;
  static Counters& get() {
    if (!_counters) _counters = new Counters();
  }

  // Bad idea if you want to deal with multithreaded things.
  // If you do, either provide an Increment(int inc_by); function instead of this,
  // or return some sort of atomic counter instead of an int.
  int& operator[](const string& key) {
    if (__DEBUG__) {
      return _counter_map.operator[](key);
    } else {
      return _bogus;
    }
  }

  // you have to deal with exposing iteration support.

private:
  Counters() {}

  // Kill copy and operator=
  void Counters(const Counters&);
  Counters& operator=(const Counters&);

  // Singleton member.
  static Counters* _counters;

  // Map to store the counters.
  std::map<string, int> _counter_map;

  // Bogus counter for opt builds.
  int _bogus;
};

, , .cpp , :

void Foo::update() {
  // Leave this in permanently, it will automatically get killed in OPT.
  Counters::get()["update-counter"]++;
}

, , :

int main(...) {
  ...
  for (Counters::const_iterator i = Counters::get().begin(); i != Countes::get().end(); ++i) {
    cout << i.first << ": " << i.second;
  }
  ...
}

, cpp-, , lib.

+2

, . , , , .

+1

What I usually do in this situation is to put the account in an anonymous namespace in the source file for the class. This means that you can add / remove a variable as you wish, it can be used anywhere in the file, and there is no chance of a name conflict. This has the disadvantage that it can only be used in the functions of the source file, and not in the lines in the header file, but I think this is what you want.

In the FooC.cpp file

namespace {
int count=0;
}

void FooC::update()
{
    ++count;
}
+1
source

Source: https://habr.com/ru/post/1704427/


All Articles