Servicios del modelo de objetos en tiempo de ejecución

Las clases CObject y CRuntimeClass encapsulan varios servicios de objetos, incluido el acceso a la información de clases en tiempo de ejecución, la serialización y la creación dinámica de objetos. Todas las clases derivadas de CObject heredan esta función.

El acceso a la información de clases en tiempo de ejecución le permite determinar información sobre la clase de un objeto en tiempo de ejecución. La capacidad de determinar la clase de un objeto en tiempo de ejecución resulta útil cuando se necesita una comprobación de tipos adicional de argumentos de función y cuando se debe escribir código con una finalidad especial basado en la clase de un objeto. La información de clases en tiempo de ejecución no es compatible directamente con el lenguaje C++.

La serialización es el proceso de escribir o leer el contenido de un objeto hacia un archivo o desde este. Puede usar la serialización para almacenar el contenido de un objeto incluso después de que se cierre la aplicación. Después, el objeto se puede leer desde el archivo cuando se reinicia la aplicación. Se dice que estos objetos de datos son "persistentes".

La creación dinámica de objetos permite crear un objeto de una clase especificada en tiempo de ejecución. Por ejemplo, los objetos document, view y frame deben admitir la creación dinámica porque el marco debe crearlos dinámicamente.

En la tabla siguiente se enumeran las macros de MFC que admiten la información de clases en tiempo de ejecución, la serialización y la creación dinámica.

Para obtener más información sobre estos servicios de objetos en tiempo de ejecución y la serialización, vea el artículo Clase CObject: Acceso a información de clases en tiempo de ejecución.

Macros de servicios del modelo de objetos en tiempo de ejecución

Nombre Descripción
DECLARE_DYNAMIC Permite el acceso a la información de clases en tiempo de ejecución (se debe usar en la declaración de la clase).
DECLARE_DYNCREATE Permite la creación dinámica y el acceso a la información de clases en tiempo de ejecución (se debe usar en la declaración de la clase).
DECLARE_SERIAL Permite la serialización y el acceso a la información de clases en tiempo de ejecución (se debe usar en la declaración de la clase).
IMPLEMENT_DYNAMIC Permite el acceso a la información de clases en tiempo de ejecución (se debe usar en la implementación de la clase).
IMPLEMENT_DYNCREATE Permite la creación dinámica y el acceso a la información en tiempo de ejecución (se debe usar en la implementación de la clase).
IMPLEMENT_SERIAL Permite la serialización y el acceso a la información de clases en tiempo de ejecución (se debe usar en la implementación de la clase).
RUNTIME_CLASS Devuelve la estructura CRuntimeClass que corresponde a la clase con nombre.

OLE requiere con frecuencia la creación dinámica de objetos en tiempo de ejecución. Por ejemplo, una aplicación de servidor OLE debe ser capaz de crear elementos OLE dinámicamente en respuesta a una solicitud de un cliente. De forma similar, un servidor de automatización debe poder crear elementos en respuesta a las solicitudes de los clientes de automatización.

La biblioteca MFC proporciona dos macros específicas de OLE.

Creación dinámica de objetos OLE

Nombre Descripción
AFX_COMCTL32_IF_EXISTS Determina si la biblioteca de controles comunes implementa la API especificada.
AFX_COMCTL32_IF_EXISTS2 Determina si la biblioteca de controles comunes implementa la API especificada.
DECLARE_OLECREATE Permite crear objetos mediante la automatización OLE.
DECLARE_OLECTLTYPE Declara las funciones miembro GetUserTypeNameID y GetMiscStatus de la clase de control.
DECLARE_PROPPAGEIDS Declara que el control OLE proporciona una lista de páginas de propiedades que van a mostrar sus propiedades.
IMPLEMENT_OLECREATE Permite crear objetos mediante el sistema OLE.
IMPLEMENT_OLECTLTYPE Implementa las funciones miembro GetUserTypeNameID y GetMiscStatus de la clase de control.
IMPLEMENT_OLECREATE_FLAGS En el archivo de implementación de cualquier clase que use DECLARE_OLECREATE debe aparecer esta macro o IMPLEMENT_OLECREATE.

AFX_COMCTL32_IF_EXISTS

Determina si la biblioteca de controles comunes implementa la API especificada.

Sintaxis

AFX_COMCTL32_IF_EXISTS(  proc );

Parámetros

proc
Puntero a una cadena terminada en null que contiene el nombre de la función o especifica el valor ordinal de esta. Si este parámetro es un valor ordinal, debe estar en la palabra de orden inferior; la palabra de orden superior debe ser cero. Este parámetro debe estar en Unicode.

Comentarios

Use esta macro para determinar si la biblioteca de controles comunes implementa la función que especifica proc (en lugar de llamar a GetProcAddress).

Requisitos

afxcomctl32.h, afxcomctl32.inl

AFX_COMCTL32_IF_EXISTS2

Determina si la biblioteca de controles comunes implementa la API especificada (se trata de la versión Unicode de AFX_COMCTL32_IF_EXISTS).

Sintaxis

AFX_COMCTL32_IF_EXISTS2( proc );

Parámetros

proc
Puntero a una cadena terminada en null que contiene el nombre de la función o especifica el valor ordinal de esta. Si este parámetro es un valor ordinal, debe estar en la palabra de orden inferior; la palabra de orden superior debe ser cero. Este parámetro debe estar en Unicode.

Comentarios

Use esta macro para determinar si la biblioteca de controles comunes implementa la función que especifica proc (en lugar de llamar a GetProcAddress). Esta macro es la versión de Unicode de AFX_COMCTL32_IF_EXISTS.

Requisitos

afxcomctl32.h, afxcomctl32.inl

DECLARE_DYNAMIC

Agrega la capacidad de acceder a información en tiempo de ejecución sobre la clase de un objeto al derivar una clase de CObject.

DECLARE_DYNAMIC(class_name)

Parámetros

class_name
Nombre real de la clase.

Comentarios

Agregue la macro DECLARE_DYNAMIC al módulo del encabezado (.h) para la clase y, después, incluya ese módulo en todos los módulos .cpp que necesiten acceso a los objetos de esta clase.

Si usa las macros DECLARE_DYNAMIC y IMPLEMENT_DYNAMIC tal como se describe, puede usar la macro RUNTIME_CLASS y la función CObject::IsKindOf para determinar la clase de los objetos en tiempo de ejecución.

Si DECLARE_DYNAMIC se incluye en la declaración de clase, IMPLEMENT_DYNAMIC debe incluirse en la implementación de clase.

Para obtener más información sobre la macro DECLARE_DYNAMIC, vea Temas de la clase CObject.

Ejemplo

Vea el ejemplo de IMPLEMENT_DYNAMIC.

Requisitos

Encabezadoafx.h:

DECLARE_DYNCREATE

Permite crear objetos de clases derivadas de CObject de forma dinámica en tiempo de ejecución.

DECLARE_DYNCREATE(class_name)

Parámetros

class_name
Nombre real de la clase.

Comentarios

El marco usa esta capacidad para crear objetos de forma dinámica. Por ejemplo, la vista creada al abrir un documento nuevo. Las clases de documento, vista y marco deben admitir la creación dinámica porque el marco debe crearlas dinámicamente.

Agregue la macro DECLARE_DYNCREATE en el módulo .h para la clase y, después, incluya ese módulo en todos los módulos .cpp que necesiten acceso a los objetos de esta clase.

Si DECLARE_DYNCREATE se incluye en la declaración de clase, IMPLEMENT_DYNCREATE debe incluirse en la implementación de clase.

Para obtener más información sobre la macro DECLARE_DYNCREATE, vea Temas de la clase CObject.

Nota:

La macro DECLARE_DYNCREATE incluye toda la función de DECLARE_DYNAMIC.

Ejemplo

Vea el ejemplo de IMPLEMENT_DYNCREATE.

Requisitos

Encabezadoafx.h:

DECLARE_OLECTLTYPE

Declara las funciones miembro GetUserTypeNameID y GetMiscStatus de la clase de control.

Sintaxis

DECLARE_OLECTLTYPE( class_name )

Parámetros

class_name
Nombre de la clase de control.

Comentarios

GetUserTypeNameID y GetMiscStatus son funciones virtuales puras, declaradas en COleControl. Dado que estas funciones son virtuales puras, deben invalidarse en la clase de control. Además de DECLARE_OLECTLTYPE, debe agregar la macro IMPLEMENT_OLECTLTYPE a la declaración de clase de control.

Requisitos

Encabezadoafxctl.h:

DECLARE_PROPPAGEIDS

Declara que el control OLE proporciona una lista de páginas de propiedades que van a mostrar sus propiedades.

Sintaxis

DECLARE_PROPPAGEIDS( class_name )

Parámetros

class_name
Nombre de la clase de control que posee las páginas de propiedades.

Comentarios

Use la macro DECLARE_PROPPAGEIDS al final de la declaración de clase. Después, en el archivo .cpp que define las funciones miembro de la clase, use la macro BEGIN_PROPPAGEIDS, las entradas de macro para cada una de las páginas de propiedades del control y la macro END_PROPPAGEIDS para declarar el final de la lista de páginas de propiedades.

Para obtener más información sobre las páginas de propiedades, vea el artículo Controles ActiveX: páginas de propiedades.

Requisitos

Encabezadoafxctl.h:

DECLARE_SERIAL

Genera el código de encabezado de C++ necesario para una clase derivada de CObject que se puede serializar.

DECLARE_SERIAL(class_name)

Parámetros

class_name
Nombre real de la clase.

Comentarios

La serialización es el proceso de escritura o lectura del contenido de un objeto un archivo y desde este.

Use la macro DECLARE_SERIAL en un módulo .h y, después, incluya ese módulo en todos los módulos .cpp que necesiten acceso a los objetos de esta clase.

Si DECLARE_SERIAL se incluye en la declaración de clase, IMPLEMENT_SERIAL debe incluirse en la implementación de clase.

La macro DECLARE_SERIAL incluye toda la función de DECLARE_DYNAMIC y DECLARE_DYNCREATE.

Puede usar la macro AFX_API a fin de exportar automáticamente el operador de extracción CArchive para las clases que usan las macros DECLARE_SERIAL y IMPLEMENT_SERIAL. Ponga entre corchetes las declaraciones de clase (ubicadas en el archivo .h) con el código siguiente:

#undef AFX_API
#define AFX_API AFX_EXT_CLASS

// <your class declarations here>

#undef AFX_API
#define AFX_API

Para obtener más información sobre la macro DECLARE_SERIAL, vea Temas de la clase CObject.

Ejemplo

class CAge : public CObject
{
public:
   void Serialize(CArchive& ar);
   DECLARE_SERIAL(CAge)

   // remainder of class declaration omitted

Requisitos

Encabezadoafx.h:

IMPLEMENT_DYNAMIC

Genera el código de C++ necesario para una clase derivada de CObject dinámica con acceso en tiempo de ejecución al nombre y la posición de la clase dentro de la jerarquía.

IMPLEMENT_DYNAMIC(class_name, base_class_name)

Parámetros

class_name
Nombre real de la clase.

base_class_name
Nombre de la clase base.

Comentarios

Use la macro IMPLEMENT_DYNAMIC en un módulo .cpp y, después, vincule el código de objeto resultante solo una vez.

Para obtener más información, vea Temas de la clase CObject.

Ejemplo

class CPerson : public CObject
{
   DECLARE_DYNAMIC(CPerson)

   // other declarations
};

 

IMPLEMENT_DYNAMIC(CPerson, CObject)

Requisitos

Encabezadoafx.h:

IMPLEMENT_DYNCREATE

Permite crear objetos de clases derivadas de CObject de forma dinámica en tiempo de ejecución cuando se usan con la macro DECLARE_DYNCREATE.

IMPLEMENT_DYNCREATE(class_name, base_class_name)

Parámetros

class_name
Nombre real de la clase.

base_class_name
Nombre real de la clase base.

Comentarios

El marco usa esta capacidad para crear objetos de forma dinámica, por ejemplo, cuando lee un objeto del disco durante la serialización. Agregue la macro IMPLEMENT_DYNCREATE en el archivo de implementación de la clase. Para obtener más información, vea Temas de la clase CObject.

Si usa las macros DECLARE_DYNCREATE y IMPLEMENT_DYNCREATE, puede usar la macro RUNTIME_CLASS y la función miembro CObject::IsKindOf para determinar la clase de los objetos en tiempo de ejecución.

Si DECLARE_DYNCREATE se incluye en la declaración de clase, IMPLEMENT_DYNCREATE debe incluirse en la implementación de clase.

Tenga en cuenta que esta definición de macro invocará el constructor predeterminado para la clase. Si la clase implementa explícitamente un constructor no trivial, también debe implementar explícitamente el constructor predeterminado. El constructor predeterminado se puede agregar a las secciones de miembro private o protected de la clase para evitar que se llame desde fuera de la implementación de clase.

Ejemplo

class CMyDynCreateObj : public CObject
{
   int m_Num;
public:
   DECLARE_DYNCREATE(CMyDynCreateObj)
   CMyDynCreateObj(int Num) { m_Num = Num; }
private:
   CMyDynCreateObj() { m_Num = 0; }  // provide default constructor only for 
                                     // dynamic creation 
};

 

IMPLEMENT_DYNCREATE(CMyDynCreateObj, CObject)

Requisitos

Encabezadoafx.h:

IMPLEMENT_OLECREATE_FLAGS

En el archivo de implementación de cualquier clase que use DECLARE_OLECREATE debe aparecer esta macro o IMPLEMENT_OLECREATE.

Sintaxis

IMPLEMENT_OLECREATE_FLAGS( class_name, external_name, nFlags,
    l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)

Parámetros

class_name
Nombre real de la clase.

external_name
Nombre del objeto expuesto a otras aplicaciones (entre comillas).

nFlags
Contiene una o varias de las marcas siguientes:

  • afxRegInsertable Permite que el control aparezca en el cuadro de diálogo Insertar objeto para objetos OLE.
  • afxRegApartmentThreading Establece el modelo de subprocesos en el registro en ThreadingModel=Apartment.
  • afxRegFreeThreading Establece el modelo de subprocesos en el registro en ThreadingModel=Free.

Puede combinar las dos marcas afxRegApartmentThreading y afxRegFreeThreading para establecer ThreadingModel=Both. Vea InprocServer32 en Windows SDK para obtener más información sobre el registro de modelos de subprocesos.

l, w1, w2, b1, b2, b3, b4, b5, b6, b7 y b8 Componentes del CLSID de la clase.

Comentarios

Nota:

Si usa IMPLEMENT_OLECREATE_FLAGS, puede especificar qué modelo de subprocesos admite el objeto mediante el parámetro nFlags. Si quiere admitir solo el modelo de subprocesos único, use IMPLEMENT_OLECREATE.

El nombre externo es el identificador expuesto a otras aplicaciones. Las aplicaciones cliente usan el nombre externo para solicitar un objeto de esta clase desde un servidor de automatización.

El id. de clase OLE es un identificador único de 128 bits para el objeto. Consta de un elemento long, dos **WORD** y ocho **BYTE**, tal y como los representan l, w1, w2 y b1 mediante b8 en la descripción de la sintaxis. El Asistente para aplicaciones y los asistentes para código crean id. de clase OLE únicos según sea necesario.

Requisitos

Encabezadoafxdisp.h:

IMPLEMENT_OLECTLTYPE

Implementa las funciones miembro GetUserTypeNameID y GetMiscStatus de la clase de control.

Sintaxis

DECLARE_OLECTLTYPE( class_name, idsUserTypeName, dwOleMisc )

Parámetros

class_name
Nombre de la clase de control.

idsUserTypeName
Id. de recurso de una cadena que contiene el nombre externo del control.

dwOleMisc
Enumeración que contiene una o varias marcas. Para obtener más información sobre esta enumeración, vea OLEMISC en Windows SDK.

Comentarios

Además de IMPLEMENT_OLECTLTYPE, debe agregar la macro DECLARE_OLECTLTYPE a la declaración de clase de control.

La función miembro GetUserTypeNameID devuelve la cadena de recursos que identifica la clase de control. GetMiscStatus devuelve los bits de OLEMISC del control. Esta enumeración especifica una colección de configuraciones que describen características diversas del control. Para obtener una descripción completa de la configuración de OLEMISC, vea OLEMISC en Windows SDK.

Nota:

Los valores predeterminados que usa el ControlWizard de ActiveX son los siguientes: OLEMISC_ACTIVATEWHENVISIBLE, OLEMISC_SETCLIENTSITEFIRST, OLEMISC_INSIDEOUT, OLEMISC_CANTLINKINSIDE y OLEMISC_RECOMPOSEONRESIZE.

Requisitos

Encabezadoafxctl.h:

IMPLEMENT_SERIAL

Genera el código de C++ necesario para una clase derivada de CObject dinámica con acceso en tiempo de ejecución al nombre y la posición de la clase dentro de la jerarquía.

IMPLEMENT_SERIAL(class_name, base_class_name, wSchema)

Parámetros

class_name
Nombre real de la clase.

base_class_name
Nombre de la clase base.

wSchema
Un "número de versión" de UINT que se codificará en el archivo para permitir que un programa de deserialización identifique y controle los datos que han creado versiones anteriores del programa. El número del esquema de clase no debe ser -1.

Comentarios

Use la macro IMPLEMENT_SERIAL en un módulo .cpp y, después, vincule el código de objeto resultante solo una vez.

Puede usar la macro AFX_API a fin de exportar automáticamente el operador de extracción CArchive para las clases que usan las macros DECLARE_SERIAL y IMPLEMENT_SERIAL. Ponga entre corchetes las declaraciones de clase (ubicadas en el archivo .h) con el código siguiente:

#undef AFX_API
#define AFX_API AFX_EXT_CLASS

// <your class declarations here>

#undef AFX_API
#define AFX_API

Para obtener más información, vea Temas de la clase CObject.

Ejemplo

IMPLEMENT_SERIAL(CAge, CObject, VERSIONABLE_SCHEMA | 2)

Requisitos

Encabezadoafx.h:

RUNTIME_CLASS

Obtiene la estructura de clase en tiempo de ejecución del nombre de una clase de C++.

RUNTIME_CLASS(class_name)

Parámetros

class_name
Nombre real de la clase (no incluido entre comillas).

Comentarios

RUNTIME_CLASS devuelve un puntero a una estructura CRuntimeClass para la clase que especifica class_name. Solo las clases derivadas de CObject declaradas con DECLARE_DYNAMIC, DECLARE_DYNCREATE o DECLARE_SERIAL devolverán punteros a una estructura CRuntimeClass.

Para obtener más información, vea Temas de la clase CObject.

Ejemplo

CRuntimeClass* prt = RUNTIME_CLASS(CAge);
ASSERT(strcmp(prt->m_lpszClassName, "CAge") == 0);

Requisitos

Encabezadoafx.h:

DECLARE_OLECREATE

Permite crear objetos de clases derivadas de CCmdTarget mediante la automatización OLE.

DECLARE_OLECREATE(class_name)

Parámetros

class_name
Nombre real de la clase.

Comentarios

Esta macro permite que otras aplicaciones habilitadas para OLE creen objetos de este tipo.

Agregue la macro DECLARE_OLECREATE en el módulo .h para la clase y, después, incluya ese módulo en todos los módulos .cpp que necesiten acceso a los objetos de esta clase.

Si DECLARE_OLECREATE se incluye en la declaración de clase, IMPLEMENT_OLECREATE debe incluirse en la implementación de clase. Una declaración de clase que use DECLARE_OLECREATE también debe usar DECLARE_DYNCREATE o DECLARE_SERIAL.

Requisitos

Encabezado: afxdisp.h

IMPLEMENT_OLECREATE

En el archivo de implementación de cualquier clase que use DECLARE_OLECREATE debe aparecer esta macro o IMPLEMENT_OLECREATE_FLAGS.

IMPLEMENT_OLECREATE(class_name, external_name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)

Parámetros

class_name
Nombre real de la clase.

external_name
Nombre del objeto expuesto a otras aplicaciones (entre comillas).

l, w1, w2, b1, b2, b3, b4, b5, b6, b7 y b8 Componentes del CLSID de la clase.

Comentarios

Nota:

Si usa IMPLEMENT_OLECREATE, de manera predeterminada solo admite el modelo de subprocesos único. Si usa IMPLEMENT_OLECREATE_FLAGS, puede especificar qué modelo de subprocesos admite el objeto mediante el parámetro nFlags.

El nombre externo es el identificador expuesto a otras aplicaciones. Las aplicaciones cliente usan el nombre externo para solicitar un objeto de esta clase desde un servidor de automatización.

El id. de clase OLE es un identificador único de 128 bits para el objeto. Consta de un elemento long, dos **WORD** y ocho **BYTE**, tal y como los representan l, w1, w2 y b1 mediante b8 en la descripción de la sintaxis. El Asistente para aplicaciones y los asistentes para código crean id. de clase OLE únicos según sea necesario.

Requisitos

Encabezado: afxdisp.h

Consulte también

Macros y globales
Aislamiento de la biblioteca de controles comunes de MFC
Clave CLSID