Search code examples
c++classinheritanceincrementradix

Changing base class value in c++


I'm facing a problem with a few inherited classes and their base class as well.

For example:

base class{

int x,y; // Doesnt really matter
int counter;

public:

class(int x, int y):x(x), y(y), counter(1){}

void add_counter(){counter++;}
//stuff
virtual ~base(){}
}



class1:public base{

 public:

 class1():base(1,2){}
 }

Every of my inherited classes (which I've a few) they all pass the x,y differently from each other. And then I want this counter to increment when I call it.

The problem I'm facing is that the counter increases ONLY on that iteration. No object is being re-constructed (because I debugged). If I call the add_counter for the class1 it will increase from 1 to 2 but if I call it again it will be the same (1 to 2).

What am I missing here?

Thank you.


Solution

  • What am I missing here?

    It seems to me that you want to keep track of the number of objects constructed whose types are derived from Base.

    In that case, you need to make counter a static member variable, which will require you to make add_counter a static member function.

    However, that will require you to:

    1. Decrement the count in the destructor.
    2. Add a copy constructor in Base to make sure that objects created using a copy constructor are also counted.

    Here's a simplified version of base to do that:

    class base
    {
       public:
    
         base() { inrement_counter(); }
    
         base(base const& copy) { inrement_counter(); }
    
         virtual ~base(){ decrement_counter(); }
    
       private:
    
         static int counter;
         static void inrement_counter() {++counter;}
         static void decrement_counter() {--counter;}
    }
    
    int base::counter = 0;
    

    If you want to keep track of the number of derived1 objects constructed, you'll need to add the bookkeeping code to derived1. You can create a class template to streamline that process.

    Example:

    template <typename T>
    struct ObjectCounter
    {
       ObjectCounter() { inrement_counter(); }
    
       ObjectCounter(ObjectCounter const& copy) { inrement_counter(); }
    
       virtual ~ObjectCounter(){ decrement_counter(); }
    
       static int counter;
       static void inrement_counter(){++counter;}
       static void decrement_counter(){--counter;}
    };
    
    template <typename T>
    int ObjectCounter<T>::counter = 0;
    
    class base
    {
    };
    
    class derived1 : public base, public ObjectCounter<derived1>
    {
    };
    
    class derived2 : public base, public ObjectCounter<derived2>
    {
    };
    
    #include <iostream>
    
    int main()
    {
       derived1 d1;
       derived2 d2;
       auto d3 = d2;
    
       std::cout << d1.counter << std::endl;
       std::cout << d2.counter << std::endl;
    }
    

    Output:

    1
    2