Declaring a pointer to a member of a class prior to the class definition impacts the size and speed of the resulting executable file. The number of bytes required to represent a pointer to a member of a class and the code required to interpret the representation may depend on whether the class is defined with no, single, multiple, or virtual inheritance.
In general, the more complex the inheritance used by a class, the greater the number of bytes required to represent a pointer to a member of the class and the larger the code required to interpret the pointer.
If you need to declare a pointer to a member of a class prior to defining the class, you must use either the /vmg command-line option or the related pointers_to_members pragma. Or you can specify the inheritance used in the class declaration using the __single_inheritance, __multiple_inheritance, or __virtual_inheritance keywords, thus allowing control of the code generated on a per-class basis. These options are explained in the following.
Note If you always declare a pointer to a member of a class after defining the class, you don’t need to use any of these options.
Microsoft attempts to optimize the representation and code generated for pointers to members by selecting the most compact representation possible. This requires defining the class the pointer to member is based upon at the point where the pointer to member is declared. The pointers_to_members pragma allows you to relax this restriction and to control the pointer size and the code required to interpret the pointer.
Syntax
#pragma pointers_to_members( pointer-declaration, [most-general-representation] )
The pointer-declaration argument specifies whether you have declared a pointer to a member before or after the associated function definition. The pointer-declaration argument can be either full_generality or best_case.
The most-general-representation argument specifies the smallest pointer representation that the compiler can safely use to reference any pointer to a member of a class in a translation unit. This argument can be single_inheritance, multiple_inheritance, or virtual_inheritance.
The pointers_to_members pragma with the best_case argument is the compiler default. You can use this default if you always define a class before declaring a pointer to a member of the class. When the compiler encounters the declaration of a pointer to a member of a class, it already has knowledge of the kind of inheritance used by the class. Thus, the compiler can use the smallest possible representation of a pointer and generate the smallest amount of code required to operate on the pointer for each kind of inheritance. This is equivalent to using /vmb on the command-line to specify best-case representation for all classes in the compilation unit.
Use the pointers_to_members pragma with the full_generality argument if you need to declare a pointer to a member of a class before defining the class. (This need can arise if you define members in two different classes that reference each other using pointers to members. For such mutually referencing classes, one class must be referenced before it is defined.) The compiler uses the most general representation for the pointer to the member. This is equivalent to the /vmg compiler option. If you specify full-generality, you must also specify single-inheritance, multiple-inheritance, or virtual-inheritance. This is equivalent to using the /vmg compiler option with the /vms, /vmm, or /vmv option.
The pointers_to_members pragma with the full_generality, single_inheritance arguments (/vms option with the /vmg option) specifies that the most general representation of a pointer to a member of a class is one that uses no inheritance or single inheritance. This is the smallest possible representation of a pointer to a member of a class. The compiler generates an error if the inheritance model of a class definition for which a pointer to a member is declared is multiple or virtual. For example, placing this statement
#pragma pointers_to_members(full_generality, single_inheritance)
before a class definition declares that all class definitions that follow use only single inheritance. Once specified, the option specified with the pointers_to_members pragma cannot be changed.
The pointers_to_members pragma with the full_generality, multiple_inheritance arguments (/vmm option with the /vmg option) specifies that the most general representation of a pointer to a member of a class is one that uses multiple inheritance. This representation is larger than that required for single inheritance. The compiler generates an error if the inheritance model of a class definition for which a pointer to a member is declared is virtual.
The pointers_to_members pragma with the full_generality, virtual_inheritance arguments (/vmv option with the /vmg option) specifies that the most general representation of a pointer to a member of a class is one that uses virtual inheritance. In terms of pointer size and the code required to interpret the pointer, this is the most expensive option. However, this option never causes an error and is the default when the full_generality argument to the pointers_to_members pragma is specified or when the /vmg command-line option is used.
Syntax
The equivalent language construction uses this syntax:
class-declaration :
class inheritance-typeopt class-name;
inheritance-type :
__single_inheritance
__multiple_inheritance
__virtual_inheritance
As shown in this example,
class __single_inheritance S;
int S::p;
regardless of compiler options or pragmas, pointers to members of class S
will use the smallest possible representation.
You can also explicitly give a forward declaration to the pointer-to-member representation of a class that has a forward declaration.
Note The same forward declaration of a class pointer-to-member representation should occur in every translation unit that declares pointers to members of that class, and the declaration should occur before the pointers to members are declared.