То, что вы действительно хотите, для вашего долгосрочного инструментария C ++ - это многопоточный, универсальный класс счетчиков отладки, который позволяет вам помещать его в любое место и использовать его, а также быть доступным из любого другого места для его печати. Если ваш код чувствителен к производительности, вы, вероятно, захотите, чтобы он автоматически ничего не делал в сборках без отладки.
Интерфейс для такого класса, вероятно, будет выглядеть так:
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;
}
...
}
Создание класса counters довольно тяжело, но если вы делаете кучу кодов cpp, вам может быть полезно написать один раз, а затем просто связать его как часть любой библиотеки.