Reputation: 93
#include<string>
#include<iostream>
using namespace std;
template<class T>
class Student_Grades
{
string name;
int NoExams;
T *grades_ptr;
static int counter;
public:
Student_Grades(string n, int no)
{
name=n;
NoExams=no;
grades_ptr=new T[no];
counter++;
}
void Print()
{
cout<<"Name: "<<name<<endl;
cout<<"NoExams: "<<NoExams<<endl;
for(int i=0; i<NoExams; i++)
{
cout<<"Grade "<<i+1<<": "<<grades_ptr[i]<<endl;
}
cout<<endl<<endl;
}
void set_grade(int index, T grade)
{
grades_ptr[index]=grade;
}
T get_grade(int index)
{
return grades_ptr[index];
}
int get_counter()
{
return counter;
}
~Student_Grades()
{
delete[] grades_ptr;
counter--;
}
};
This code will create a different counter for every template specialization. How do I make the counter global, meaning it will be incremented each time I create an object? In the Main, I created 3 Student_Grades objects, one with int specialization. one with double and one with char. The counter gives me 1. How do I get it to give me 3?
Upvotes: 3
Views: 185
Reputation: 50548
You can use a base class the aim of which is to count the number of instances:
#include<cassert>
struct B {
B() { cnt++; }
virtual ~B() { cnt--; }
static int cnt;
};
int B::cnt = 0;
template<typename T>
struct D: B {
D(): B{} { }
};
int main() {
D<int> d1;
D<float> d2;
assert(B::cnt == 2);
}
This way, it doesn't depend on the type of the specialization.
A slightly more configurable solution would be this one:
#include<cassert>
struct C {
C() { cnt++; }
virtual ~C() { cnt--; }
static int cnt;
};
int C::cnt = 0;
template<typename T, class Counter = C>
struct D: Counter { };
int main() {
D<int> d1;
D<float> d2;
assert(C::cnt == 2);
}
This one if you don't want to rely on inheritance:
#include<cassert>
struct C {
C() { cnt++; }
~C() { cnt--; }
static int cnt;
};
int C::cnt = 0;
template<typename T, class Counter = C>
struct D { const Counter c; };
int main() {
D<int> d1;
D<float> d2;
assert(C::cnt == 2);
}
And so on...
Upvotes: 2