Also see:
http://www.gammon.com.au/forum/?id=11105
for details about a walkthrough of making a C++ class.
Tracing class construction
Before pressing on with concrete examples of creating C++ objects, I will present a small "trace" class that lets us see when objects are being created and destroyed.
This class can be used as a base class for other classes, or inserted into a different class.
Output
The obj_trace class is templated to take a letter which indicates which type it is (eg. class A or class B and so on).
Each type (eg. class A) maintains a static count so you can see how many types of that class are created, and which order they are created/destroyed.
The program above illustrates the various way of using the obj_trace class:
http://www.gammon.com.au/forum/?id=11105
for details about a walkthrough of making a C++ class.
Tracing class construction
Before pressing on with concrete examples of creating C++ objects, I will present a small "trace" class that lets us see when objects are being created and destroyed.
This class can be used as a base class for other classes, or inserted into a different class.
#include <iostream>
using namespace std;
template <char id = 'X'>
class obj_trace
{
public:
// default constructor
obj_trace () : which (++count)
{
cout << "object " << id << which << " constructed" << endl;
}
// destructor
~obj_trace ()
{
cout << "object " << id << which << " destroyed" << endl;
}
// copy constructor
obj_trace (const obj_trace & rhs) : which (++count)
{
cout << "object " << id << which << " copy constructed" << endl;
}
// operator= (assignment)
obj_trace & operator= (const obj_trace & rhs)
{
cout << "object " << id << which << " operator=" << endl;
return *this;
}
private:
static int count; // count of this type of object
int which; // which one this is
}; // end of obj_trace
template <> int obj_trace<'A'>::count = 0;
template <> int obj_trace<'B'>::count = 0;
template <> int obj_trace<'C'>::count = 0;
template <> int obj_trace<'D'>::count = 0;
class A : public obj_trace<'C'>
{
int x;
};
class B
{
obj_trace<'D'> y;
};
int main (void)
{
cout << "creating a, b" << endl;
obj_trace<'A'> a, b;
cout << "creating c, d" << endl;
obj_trace<'B'> c, d;
cout << "creating: A e" << endl;
A e;
cout << "creating: B f" << endl;
B f;
cout << "program end" << endl;
return 0;
}
Output
creating a, b
object A1 constructed
object A2 constructed
creating c, d
object B1 constructed
object B2 constructed
creating: A e
object C1 constructed
creating: B f
object D1 constructed
program end
object D1 destroyed
object C1 destroyed
object B2 destroyed
object B1 destroyed
object A2 destroyed
object A1 destroyed
The obj_trace class is templated to take a letter which indicates which type it is (eg. class A or class B and so on).
Each type (eg. class A) maintains a static count so you can see how many types of that class are created, and which order they are created/destroyed.
The program above illustrates the various way of using the obj_trace class:
- Directly, like this:
obj_trace<'A'> a;
- To derive a class from, like this:
class A : public obj_trace<'C'> { int x; };
Doing this will tell you when the class (class A in this case) is constructed/destroyed.
- To insert inside a class (or function), like this:
class B { obj_trace<'D'> y; };
Doing this will tell you when the class's members (variable y in this case) area constructed/destroyed.