2

I want to make a base class that helps me store some info about the class itself. One of these variables is a instance counter. It counts the instances of the classes.

Normally I would just use a static member variable, that I increase when the base constructor is called and decreased when the base destructor is called. Problem being that static member variables dont get re-created for each derived class. Instead the access is inherited, making it not a individual counter but one that simply counts the amount of base classes inherited. That is not my goal.

What I want:

  • The counter should work without having to do anything in the derived class other than deriving from base
  • The method shouldnt require much processing power or memory.

What I have tried:

  • Using a static member (failed obviously)
  • Using a normal member (failed obviously, was clear from the start)

What is the proper way to do this sort of thing.

MoustacheSpy
  • 743
  • 1
  • 6
  • 27

2 Answers2

2

How about template class, something like:

template <typename Derived, typename ... Bases>
class Counter : Bases... {
public:
    Counter() { ++count; }
    Counter(const Counter& rhs) : Bases(rhs)... { ++count; }
    Counter(Counter&& rhs)  : Bases(std::move(rhs))...{ ++count; }

    ~Counter() { --count; }

private:
    static std::size_t count;
};

template <typename Derived, typename ... Bases>
std::size_t Counter<Derived, Bases...>::count = 0;

so your class would be

class MyClass : Counter<MyClass, Base>
{
    // Implementation...
};
Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • Is it possible to implement this with a single Base class (that one would be the template) and no additional counter class? – MoustacheSpy Nov 30 '17 at 10:00
  • You may use `class MyClass : Counter {};` if I understand you correctly. But then if you have also `MyClass2 : Counter`, they won't have common base. – Jarod42 Nov 30 '17 at 10:09
  • I meant that I dont want to define a class named "counter". I only want to use "base", since "base" also includes the instance Counter. Making 2 classes for this is not something I wish to do, since it is confusing. Sorry that I didnt word it right the first time :( – MoustacheSpy Nov 30 '17 at 12:51
  • You can have: `template struct Base : Counter> {}` or rename `Counter` to `Base` (but if you had other functionality, you broke the principle: "one class, one responsibility"). – Jarod42 Nov 30 '17 at 13:00
0

You MUST use an atomic variable for the counter.

If you must use C++03, which has no atomics support. There is boost::atomic, or call the OS directly:

Michaël Roy
  • 6,338
  • 1
  • 15
  • 19