问题
I've recently learned about CRTP and have been practicing some of the better documented code examples out there to understand it better. Currently the block of code I have is able to count the instances of different derived classes but what if I want to find the total of all instances regardless of class? Here is the code I have:
template <typename CountedType>
class countable {
static unsigned count_;
public:
countable() { ++count_; }
countable(countable const&) { ++count_; }
~countable() { --count_; }
static unsigned n_alive() { return count_; }
};
template <typename CountedType>
unsigned countable<CountedType>::count_ = 0;
template <typename CharT>
class BasicMyString : public basic_string < CharT >, public countable<BasicMyString<CharT>> { };
typedef BasicMyString<char> MyString;
typedef BasicMyString<wchar_t> WMyString;
template <typename T>
class MyVector : public vector<T>, public countable<MyVector<T>> {};
int main() {
MyString s1, s2;
WMyString wms;
MyVector<double> v;
cout << "Number of MyString: " << MyString::n_alive() << endl;
cout << "Number of WMyString: " << WMyString::n_alive() << endl;
cout << "Number of MyVector: " << MyVector<double>::n_alive() << endl;
//cout << "Total number of objects: " << countable::n_alive() << endl;
}
The last line that is currently commented out is the way I want to be able to call to see how many total objects there currently are. I know I can find the total out another way by creating a global counter and creating a new function within the class to return that global count but I want to be able to call it like this, without defining a templated argument. Do I have to make an Adapter sort of interface or is there an easier way of implementing this?
Thanks.
回答1:
Solution 1
Make countable
a derived class of a non-template class, such as countable_base
, and move all the counting code to the base class.
class countable_base {
static unsigned count_;
public:
countable_base() { ++count_; }
countable_base(countable_base const&) { ++count_; }
~countable_base() { --count_; }
static unsigned n_alive() { return count_; }
};
unsigned countable_base::count_ = 0;
template <typename CountedType>
class countable : public countable_base {};
Solution 2
Make countable
a regular class.
class countable {
static unsigned count_;
public:
countable() { ++count_; }
countable(countable const&) { ++count_; }
~countable() { --count_; }
static unsigned n_alive() { return count_; }
};
unsigned countable::count_ = 0;
回答2:
You may create an extra class to do the count which will be the base of your current template countable
class, something like:
class countable_total {
static unsigned count_;
protected:
countable_total() { ++count_; }
countable_total(countable_total const&) { ++count_; }
~countable_total() { --count_; }
public:
static unsigned n_alive() { return count_; }
};
template <typename CountedType>
class countable : public countable_total {
static unsigned count_;
public:
countable() { ++count_; }
countable(countable const&) { ++count_; }
~countable() { --count_; }
static unsigned n_alive() { return count_; }
};
template <typename CountedType>
unsigned countable<CountedType>::count_ = 0;
// in cpp
unsigned countable_total::count_ = 0;
来源:https://stackoverflow.com/questions/25066469/crtp-counting-individual-classes-and-total-count