#include <ccobject.h>
Inheritance diagram for CCObject:
Public Member Functions | |
virtual CCRuntimeClass * | GetRuntimeClass () const |
This function allows access to the CCRuntimeClass object for this class, which in turn allows dynamic classing and construction. This function is automatically overridden on derived classes if you use the CC_DECLARE_... and CC_IMPLEMENT_... macros. | |
virtual | ~CCObject () |
CCObject destructor - does nothing at present. Ought to be inline. | |
BOOL | IsKindOf (const CCRuntimeClass *pClass) const |
This function will return TRUE if the object is of the same class as that specified by pClass, or if it is derived from the class specified by pClass. | |
virtual void | AssertValid () const |
Ensures that a an instance of CCObject (or a derived class) is valid. In the base case, this means that 'this' is not a NULL pointer. You can override this function to provide whatever validation you want for your class (preferably using ENSURE/ASSERT). | |
virtual void | Dump (CDumpContext &dc) const |
Print out the contents of an object derived from CCObject. You may override this function to dump whatever information you deem useful or helpful about this object - it is used, amongst other things, in diagnostic memory dumps. The default action if you do not override this function is to print:. | |
Static Public Member Functions | |
static CCRuntimeClass * | GetRuntimeClassByName (LPCTSTR pClassName) |
This function allows access to the CCRuntimeClass object for this class, which in turn allows dynamic classing and construction. This function is automatically overridden on derived classes if you use the CC_DECLARE_... and CC_IMPLEMENT_... macros. | |
static CCRuntimeClass * | GetMyClass () |
Static Public Attributes | |
static CCRuntimeClass | cc_classCCObject |
Protected Member Functions | |
CCObject () | |
CCObject constructor - does nothing at present. Ought to be inline. | |
Private Member Functions | |
CCObject (const CCObject &objectSrc) | |
void | operator= (const CCObject &objectSrc) |
In your class declaration (preferably at the beginning) you should put: MonoOn CC_DECLARE_DYNAMIC(MyClass) MonoOff where MyClass is the name of your class. Note that there is semi-colon at the end of the line. Then you should put the following in your class definition (.cpp file): MonoOn CC_IMPLEMENT_DYNAMIC(MyClass, BaseClass) MonoOff where BaseClass is the name of the class that MyClass is derived from. This may be CCObject, or it may be something else if you have derived your class from another class which is in turn derived from CCObject, and so on. THe position of this line is not important (as long as it is not inside any functions), but it must be present for dynamic class information to work. Also note that there is no semi-colon at the end of this line.
Declaring your class as dynamic in this way allows you to test its type when you don't know what it will be at runtime. For example:
MonoOn void *GetAnObject();
CCObject *pObject = GetAnObject();
if (pObject->IsKindOf(CC_RUNTIME_CLASS(MyClass)) do_something; else if (pObject->IsKIndOf(CC_RUNTIME_CLASS(Node)) do_something else; else ... MonoOff
The special macro CC_RUNTIME_CLASS should be used when trying to identify an object at runtime. It evaluates to a reference to the structure containing the runtime class information for the specified class - the IsKindOf() function then simply compares pointers to see if the objects are from the same class. Therefore this type-checking is quite efficient.
When your class is declared as dynamic, it also means that memory dumps are more helpful because instead of saying "CCObject at $247247" they will say "MyClass at $247247", so we know exactly what kind of objects are not being cleaned up.
Deriving a class from CCObject can be quite an 'expensive' thing to do, as it means that the objects have virtual function tables. However, in debug builds, the dynamic class info can be very useful. For this reason, there are a number of macros which enable you to have dynamic class facilities in debug builds, but not in retail builds. These macros are as follows:
MonoOn CC_CLASS_MEMDUMP MonoOff This macro should be used in class declarations like this:
MonoOn class MyClass : public CC_CLASS_MEMDUMP { ... }; MonoOff
This macro will evaulate to SimpleCCObject in retail builds, and CCObject in debug builds. You then need to use the CC_DECLARE_MEMDUMP and CC_IMPLEMENT_MEMDUMP macros in your class declaration and definition. These macros are similar to the CC_DECLARE_DYNAMIC and CC_IMPLEMENT_DYNAMIC macros described above, and the parameters are the same. Doing all this gives you a class that uses the correct new operator in retail builds, but which also provides runtime-classing (and hence more helpful memory diagnostics) in debug builds.
Dynamic Construction
You may also want to dynamically create objects at run-time, when the type of the object you want to create is unknown at compile-time. An example of this is to copy an object. There are another set of macros that provide all the functionality of the CC_..._DYNAMIC macros, but which also provide dynamic object creation. The macros are: MonoOn CC_DECLARE_DYNCREATE CC_IMPLEMENT_DYNCREATE MonoOff The use and parameters of these macros are the same as for the DYNAMIC macros described above.
To copy an object derived from CCObject you need to get the CCRuntimeClass object associated with the class, and then call a function of that object to create a new one. For example:
MonoOn Some arbitrary object CCObject *pObject = (CCObject *) SomeObject;
Get the runtime class info on this object CCRuntimeClass *pCCRuntimeClass = pObject->GetRuntimeClass();
Create another object of the same type CCObject *pNewObject = pCCRuntimeClass->CreateObject();
It really is the correct type of object... ASSERT(pNewObject(IsKindOf(pCCRuntimeClass))); // This will succeed MonoOff
Definition at line 376 of file ccobject.h.
|
CCObject destructor - does nothing at present. Ought to be inline.
Definition at line 1289 of file ccobject.cpp.
|
|
CCObject constructor - does nothing at present. Ought to be inline.
Definition at line 1270 of file ccobject.cpp.
|
|
|
|
Ensures that a an instance of CCObject (or a derived class) is valid. In the base case, this means that 'this' is not a NULL pointer. You can override this function to provide whatever validation you want for your class (preferably using ENSURE/ASSERT).
Definition at line 1210 of file ccobject.cpp.
|
|
Print out the contents of an object derived from CCObject. You may override this function to dump whatever information you deem useful or helpful about this object - it is used, amongst other things, in diagnostic memory dumps. The default action if you do not override this function is to print:.
where ClassName is the name of the class that the object is an instance of, and address is the value of the 'this' pointer - you should provide at least this level of functionality if you override the function.
Definition at line 1243 of file ccobject.cpp. 01244 { 01245 #ifdef _DEBUG 01246 char Msg[256]; 01247 _stprintf(Msg, "%s at %p ", GetRuntimeClass()->m_lpszClassName, (void*)this); 01248 afxDump << Msg; 01249 #else 01250 dc; 01251 #endif //_DEBUG 01252 }
|
|
Reimplemented in CamResource. Definition at line 861 of file ccobject.cpp. 00862 { 00863 return &CCObject::cc_classCCObject; 00864 }
|
|
This function allows access to the CCRuntimeClass object for this class, which in turn allows dynamic classing and construction. This function is automatically overridden on derived classes if you use the CC_DECLARE_... and CC_IMPLEMENT_... macros.
Reimplemented in CamResource. Definition at line 854 of file ccobject.cpp. 00855 { 00856 return &CCObject::cc_classCCObject; 00857 }
|
|
This function allows access to the CCRuntimeClass object for this class, which in turn allows dynamic classing and construction. This function is automatically overridden on derived classes if you use the CC_DECLARE_... and CC_IMPLEMENT_... macros.
Definition at line 889 of file ccobject.cpp. 00890 { 00891 CCRuntimeClass* pClass = CCRuntimeClass::pFirstClass; 00892 do 00893 { 00894 if( 0 == camStrcmp(pClassName,pClass->m_lpszClassName) ) 00895 { 00896 return (pClass); 00897 } 00898 } 00899 while( ( pClass = pClass->m_pNextClass ) != NULL ); 00900 00901 return (NULL); 00902 }
|
|
This function will return TRUE if the object is of the same class as that specified by pClass, or if it is derived from the class specified by pClass. Technical Notes: This function relies on the fact that all classes derived from CCObject which have been declared and defined as having dynamic class support, will have a static CCRuntimeClass object as a data member. This object will also have been inserted into CCRuntimeClass's list of CCObject-derived classes (see CC_CLASSINIT). Therefore, this function simply uses GetRuntimeClass() to get the CCRuntimeClass object for the CCObject-derived object in question, and compares the pointers - if the objects are of the same class, both pointers will point to the same static CCRuntimeClass data member. If the pointers are not the same, the function follows the base class chain backwards until either the object is found to be derived from the class specified by pClass, or until the base class chain comes to an end, in which case the objects are not of the same class, so FALSE is returned. Definition at line 942 of file ccobject.cpp. 00943 { 00944 // Do some sanity checking 00945 ENSURE( this != NULL, 00946 "CCObject::IsKindOf: Object pointer is null"); 00947 00948 // It had better be in valid memory, at least for CCObject size 00949 ENSURE( IsValidAddress(this, sizeof(CCObject)), 00950 "CCObject::IsKindOf: Object is in invalid memory area"); 00951 00952 // Get the runtime class information for this object 00953 register CCRuntimeClass* pClassThis = GetRuntimeClass(); 00954 00955 // Sanity checks 00956 ENSURE( pClass != NULL, 00957 "CCObject::IsKindOf: pClass pointer is null"); 00958 ENSURE(pClassThis != NULL, 00959 "CCObject::IsKindOf: pClassThis pointer is null"); 00960 00961 // Check for objects of the same class, or walk the base class chain until 00962 // it runs out, or we find a match. 00963 while (pClassThis != NULL) 00964 { 00965 if (pClassThis == pClass) 00966 return TRUE; 00967 pClassThis = pClassThis->m_pBaseClass; 00968 } 00969 00970 // No match - these classes are not the same. 00971 return FALSE; 00972 }
|
|
|
|
Initial value: { szCCObject, sizeof(CCObject), 0xffff, NULL, NULL } Definition at line 405 of file ccobject.h. |