I've implemented in C# counter using CRTP, but I don't know why it doesn't count down for some types:
using System;
using Type1 = C<char>;
using Type2 = C<int>;
class ExistingObjectCounter<CountedType>
{
private static uint existingObjects = 0;
protected ExistingObjectCounter()
{
++existingObjects;
}
~ExistingObjectCounter()
{
Console.WriteLine("Destruction of " + this + " number " + existingObjects);
--existingObjects;
}
public static uint GetNumberOfLivingObjects
{
get
{
return existingObjects;
}
}
}
class C<T> : ExistingObjectCounter<C<T>>
{
public C()
{}
public C(C<T> m)
{}
};
class ZliczaczObiektow
{
public static void createManyCClassWithStringArgument()
{
for(int i=0; i<10;++i)
new C<String>();
}
public static void Main()
{
Type1 c1 = new Type1(), c2 = new Type1(), c3 = new Type1(c2);
var ws1 = new Type2();
Console.WriteLine("existing objects of class " + c1.GetType() + ": "
+ Type1.GetNumberOfLivingObjects);
Console.WriteLine("existing objects of class " + ws1.GetType() + ": "
+ Type2.GetNumberOfLivingObjects);
createManyCClassWithStringArgument();
{
Type1 c4 = new Type1(), c5 = new Type1();
var ws2 = new Type2();
Console.WriteLine("existing objects of class " + c4.GetType() + ": "
+ Type1.GetNumberOfLivingObjects);
Console.WriteLine("existing objects of class " + ws2.GetType() + ": "
+ Type2.GetNumberOfLivingObjects);
createManyCClassWithStringArgument();
}
System.GC.Collect();
Console.WriteLine("existing objects of class " + c1.GetType() + ": "
+ Type1.GetNumberOfLivingObjects);
Console.WriteLine("existing objects of class " + ws1.GetType() + ": "
+ Type2.GetNumberOfLivingObjects);
Console.WriteLine("existing objects of class C<String>: "
+ C<String>.GetNumberOfLivingObjects);
Console.ReadKey();
}
}
the output is:
existing objects of class C`1[System.Char]: 3
existing objects of class C`1[System.Int32]: 1
existing objects of class C`1[System.Char]: 5
existing objects of class C`1[System.Int32]: 2
existing objects of class C`1[System.Char]: 5
existing objects of class C`1[System.Int32]: 2
existing objects of class C<String>: 20
Destruction of C`1[System.String] number 20
Destruction of C`1[System.String] number 19
Destruction of C`1[System.String] number 18
Destruction of C`1[System.String] number 17
Destruction of C`1[System.String] number 16
Destruction of C`1[System.String] number 15
Destruction of C`1[System.String] number 14
Destruction of C`1[System.String] number 13
Destruction of C`1[System.String] number 12
Destruction of C`1[System.String] number 11
Destruction of C`1[System.String] number 10
Destruction of C`1[System.String] number 9
Destruction of C`1[System.String] number 8
Destruction of C`1[System.String] number 7
Destruction of C`1[System.String] number 6
Destruction of C`1[System.String] number 5
Destruction of C`1[System.String] number 4
Destruction of C`1[System.String] number 3
Destruction of C`1[System.String] number 2
Destruction of C`1[System.String] number 1
EDIT: My question is why counters don't go down in some cases, but in another do? Why Type1 and Type2 don't have destructor being called in the end of the program, but on the other hand C parametrised with String has destructor being called?