2008-12-1CRuntimeClass DECLARE_DYNAMIC IMPLEMENT_DYNAMIC

来源:互联网 发布:人工神经网络算法代码 编辑:程序博客网 时间:2024/05/12 06:52
  1. struct CRuntimeClass{
  2.     LPCSTR m_lpszClassName;
  3.     int m_nObjectSize;
  4.     UINT m_wSchema;             // schema number of the loaded class
  5.     Cobject* (PASCAL* m_pfnCreateObject)();    //NULL => abstract class
  6.     CRuntimeClass* m_pBaseClass;
  7.     
  8.     //linked list of registered class
  9.     static CRuntimeClass* pFirstClass;
  10.     CRuntimeClass* m_pNextClass;
  11. };
  12. #define RUNTIME_CLASS(class_name)   /
  13.     (&class_name::class##class_name)
  14. struct AFX_CLASSINIT
  15.     {AFX_CLASSINIT(CRuntimeClass* pNewClass)};
  16. AFX_CLASSINIT::AFX_CLASSINIT(CRuntimeClass* pNewClass)
  17. {
  18.     pNewClass->m_pNextClass = CRuntimeClass::pFirstClass:
  19.     CRuntimeClass::pFirstClass = pNewClass;
  20. }
  21. #define DECLARE_DYNAMIC(class_name) /
  22. public: /
  23.     static CRuntimeClass class##class_name; /
  24.     virtual CRuntimeClass* GetRuntimeClass() const;
  25. #define IMPLEMENT_DYNAMIC(class_name,base_class_name) /
  26.     _IMPLEMENT_DYNAMIC(class_name,base_class_name,0xFFFF,NULL)  
  27.     
  28. #define IMPLEMENT_DYNAMIC(class_name,base_class_name,wSchema,pfnNew)    /
  29.     /*  */
  30.     static char _lpsz##class_name[] = #class_name;  /
  31.     CRuntimeClass class_name::class##class_name = { /
  32.         _lpsz##class_name,sizeof(class_name),wSchema,pfnNew,    /
  33.         RUNTIME_CLASS(base_class_name),NULL};   /
  34.         
  35.     /*  */
  36.     static AFX_CLASSINIT _init_##class_name(&class_name::class##class_name);    /   /* init  class##class_name*/
  37.     CRuntimeClass* class_name::GetRuntimeClass() const    /
  38.         {return &class_name::class##class_name;}
  39.     

    

1、构造函数设为私有时(无访问控制时默认)、虚函数?

    一般情况下,不应该声明为私有,因为在实例在创建之前,无法正常访问私有成员、;有人说这样做也不是面向对象的初衷。

    vtable?这个东西在实例化后才会有。。。

    如果按照正常方式初始化实例化对象(总之会自动调用构造函数的地方)会出错误C2248。声明在全局数据区、栈中、new在堆上。

    但是可以通过其它手段设置成员变量来初始化实例,可以通过其它手段(因为私有成员在对象初始化之前不能被普通成员函数访问==>static 成员函数、友元函数或者友元类中)

2、this指针

    另一种是成员中自动添加

4、封装、继承、Object slicing、多态、宏定义

    可见性

     成员函数名() const;不能够修改对象成员变量,在不操作成员变量的函数加上这可以增强程序的健壮性。

    虚函数(成员函数覆盖)、成员变量(变量名)覆盖的另一种行为方式表现在这里

    struct在C++中也存在构造函数。。。

    自己作为成员变量或者引用

 

 

其它问题:

    编译控制

    

    宏定义实现

    

    struct 实现基于对象,类似对象

 

    调用约定(Calling   convention)决定以下内容:

        函数参数的压栈顺序

        由调用者还是被调用者把参数弹出栈

        产生函数修饰名的方法。

 

_cdecl    
   
  按从右至左的顺序压参数入栈,由调用者把参数弹出栈。对于“C”函数或者变量,修饰名是在函数名前加下划线。对于“C++”函数,有所不同。    
   
  如函数void   test(void)的修饰名是_test;对于不属于一个类的“C++”全局函数,修饰名是?test@@ZAXXZ。    
   
  这是MFC缺省调用约定。由于是调用者负责把参数弹出栈,所以可以给函数定义个数不定的参数,如printf函数。    
   
   
  _stdcall    
   
  按从右至左的顺序压参数入栈,由被调用者把参数弹出栈。对于“C”函数或者变量,修饰名以下划线为前缀,然后是函数名,然后是符号“@”及参数的字节数,如函数int   func(int   a,   double   b)的修饰名是_func@12。对于“C++”函数,则有所不同。    
   
  所有的Win32   API函数都遵循该约定。    
   
   
  _fastcall    
   
  头两个DWORD类型或者占更少字节的参数被放入ECX和EDX寄存器,其他剩下的参数按从右到左的顺序压入栈。由被调用者把参数弹出栈,对于“C”函数或者变量,修饰名以“@”为前缀,然后是函数名,接着是符号“@”及参数的字节数,如函数int   func(int   a,   double   b)的修饰名是@func@12。对于“C++”函数,有所不同。    
   
  未来的编译器可能使用不同的寄存器来存放参数。    
   
   
  thiscall    
   
  仅仅应用于“C++”成员函数。this指针存放于CX寄存器,参数从右到左压栈。thiscall不是关键词,因此不能被程序员指定。    
   
   
  naked   call    
   
  采用1-4的调用约定时,如果必要的话,进入函数时编译器会产生代码来保存ESI,EDI,EBX,EBP寄存器,退出函数时则产生代码恢复这些寄存器的内容。naked   call不产生这样的代码。    
   
  naked   call不是类型修饰符,故必须和_declspec共同使用,如下:    
   
  __declspec(   naked   )   int   func(   formal_parameters   )    
   
  {    
   
  //   Function   body    
   
  }    
   
   
  过时的调用约定    
   
  原来的一些调用约定可以不再使用。它们被定义成调用约定_stdcall或者_cdecl。例如:    
   
  #define   CALLBACK   __stdcall    
   
  #define   WINAPI   __stdcall    
   
  #define   WINAPIV   __cdecl    
   
  #define   APIENTRY   WINAPI    
   
  #define   APIPRIVATE   __stdcall    
   
  #define   PASCAL   __stdcall