You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -14,7 +14,7 @@ These macros control specific compiler features.
14
14
|[`_ATL_ALL_WARNINGS`](#_atl_all_warnings)|A symbol that enables errors in projects converted from previous versions of ATL.|
15
15
|[`_ATL_APARTMENT_THREADED`](#_atl_apartment_threaded)|Define if one or more of your objects use apartment threading.|
16
16
|[`_ATL_CSTRING_EXPLICIT_CONSTRUCTORS`](#_atl_cstring_explicit_constructors)|Makes certain `CString` constructors explicit, preventing any unintentional conversions.|
17
-
|[`_ATL_ENABLE_PTM_WARNING`](#_atl_enable_ptm_warning)|Define this macro to require C++ standard syntax. It generates the C4867 compiler error when non-standard syntax is used to initialize a pointer to a member function.|
17
+
|[`_ATL_ENABLE_PTM_WARNING`](#_atl_enable_ptm_warning)|Define this macro to require C++ standard syntax. It generates the C4867 compiler error when nonstandard syntax is used to initialize a pointer to a member function.|
18
18
|[`_ATL_FREE_THREADED`](#_atl_free_threaded)|Define if one or more of your objects use free or neutral threading.|
19
19
|[`_ATL_MODULES`](#_ATL_MODULES)|Allows you to compile ATL projects with [permissive-](../../build/reference/permissive-standards-conformance.md) and use ATL with [C++ modules](../../cpp/modules-cpp.md).|
20
20
|[`_ATL_MULTI_THREADED`](#_atl_multi_threaded)|A symbol that indicates the project has objects marked as Both, Free or Neutral. The macro [`_ATL_FREE_THREADED`](#_atl_free_threaded) should be used instead.|
@@ -64,7 +64,7 @@ New projects have this `#define` set in *pch.h* (*stdafx.h* in Visual Studio 201
64
64
65
65
Define if one or more of your objects use apartment threading.
66
66
67
-
```
67
+
```cpp
68
68
_ATL_APARTMENT_THREADED
69
69
```
70
70
@@ -88,7 +88,7 @@ By using the `_T` macro on all constructor string arguments, you can define `_AT
Define this macro in order to force the use of ANSI C++ standard-conforming syntax for pointer to member functions. Using this macro causes the C4867 compiler error to be generated when non-standard syntax is used to initialize a pointer to a member function.
91
+
Define this macro in order to force the use of ANSI C++ standard-conforming syntax for pointer to member functions. Using this macro causes the C4867 compiler error to be generated when nonstandard syntax is used to initialize a pointer to a member function.
92
92
93
93
```cpp
94
94
#define_ATL_ENABLE_PTM_WARNING
@@ -100,7 +100,7 @@ The ATL and MFC libraries have been changed to match the Microsoft C++ compiler'
100
100
101
101
When [`_ATL_ENABLE_PTM_WARNING`](#_atl_enable_ptm_warning) isn't defined (the default case), ATL/MFC disables the C4867 error in macro maps (notably message maps) so that code that was created in earlier versions can continue to build as before. If you define `_ATL_ENABLE_PTM_WARNING`, your code should conform to the C++ standard.
102
102
103
-
However, the non-standard form has been deprecated. You need to move existing code to C++ standard syntax. For example, the following code:
103
+
However, the nonstandard form has been deprecated. You need to move existing code to C++ standard syntax. For example, the following code:
A symbol that indicates the project will have objects that are marked as Both, Free or Neutral.
135
+
A symbol that indicates the project has objects that are marked as Both, Free or Neutral.
136
136
137
137
```
138
138
_ATL_MULTI_THREADED
@@ -193,11 +193,11 @@ A symbol that indicates a function shouldn't be inlined.
193
193
### Parameters
194
194
195
195
*`myfunction`*\
196
-
The function that should not be inlined.
196
+
The function that shouldn't be inlined.
197
197
198
198
### Remarks
199
199
200
-
Use this symbol if you want to ensure a function does not get inlined by the compiler, even though it must be declared as inline so that it can be placed in a header file. Expands to `__declspec(noinline)`.
200
+
Use this symbol if you want to ensure a function doesn't get inlined by the compiler, even though it must be declared as inline so that it can be placed in a header file. Expands to `__declspec(noinline)`.
@@ -15,7 +14,7 @@ Classes and structures can contain members that occupy less storage than an inte
15
14
16
15
## Remarks
17
16
18
-
The (optional) *declarator* is the name by which the member is accessed in the program. It must be an integral type (including enumerated types). The *constant-expression* specifies the number of bits the member occupies in the structure. Anonymous bit fields — that is, bit-field members with no identifier — can be used for padding.
17
+
The (optional) *declarator* is the name by which the member is accessed in the program. It must be an integral type (including enumerated types). The *constant-expression* specifies the number of bits the member occupies in the structure. Anonymous bit fields—that is, bit-field members with no identifier—can be used for padding.
19
18
20
19
> [!NOTE]
21
20
> An unnamed bit field of width 0 forces alignment of the next bit field to the next **type** boundary, where **type** is the type of the member.
@@ -33,20 +32,21 @@ struct Date {
33
32
};
34
33
```
35
34
36
-
The conceptual memory layout of an object of type `Date` is shown in the following figure.
35
+
The conceptual memory layout of an object of type `Date` is shown in the following figure:
37
36
38
-
 <br/>
39
-
Memory Layout of Date Object
37
+
:::image type="complex" source="../cpp/media/vc38uq1.png" alt-text="Diagram of the memory layout of a date object, showing where the n WeekDay, n MonthDay, n Month, and n Year bit fields are located.":::
38
+
32 bits of memory are displayed in a row. Starting with the least significant bit, 3 bits are for nWeekDay. The next 6 bits are for nMonthDay. The next 5 bits are for nMonth. The next 2 bits are unused. The next 8 bits are for nYear. The remaining 8 bits are unused.
39
+
:::image-end:::
40
40
41
-
Note that `nYear` is 8 bits long and would overflow the word boundary of the declared type, **`unsigned short`**. Therefore, it is begun at the beginning of a new **`unsigned short`**. It is not necessary that all bit fields fit in one object of the underlying type; new units of storage are allocated, according to the number of bits requested in the declaration.
41
+
`nYear` is 8 bits long, which would overflow the word boundary of the declared type, **`unsigned short`**. Therefore, it starts at the beginning of a new **`unsigned short`**. It isn't necessary that all bit fields fit in one object of the underlying type; new units of storage are allocated, according to the number of bits requested in the declaration.
42
42
43
43
**Microsoft Specific**
44
44
45
-
The ordering of data declared as bit fields is from low to high bit, as shown in the figure above.
45
+
The ordering of data declared as bit fields is from low to high bit, as shown in the previous figure.
46
46
47
47
**END Microsoft Specific**
48
48
49
-
If the declaration of a structure includes an unnamed field of length 0, as shown in the following example,
49
+
If the declaration of a structure includes an unnamed field of length 0, as shown in the following example:
50
50
51
51
```cpp
52
52
// bit_fields2.cpp
@@ -60,14 +60,15 @@ struct Date {
60
60
};
61
61
```
62
62
63
-
then the memory layout is as shown in the following figure:
63
+
Then the memory layout is as shown in the following figure:
64
64
65
-
 <br/>
66
-
Layout of Date Object with Zero-Length Bit Field
65
+
:::image type="complex" source="../cpp/media/vc38uq2.png" alt-text="Diagram of the layout of a Date object, with a zero length bit field, which forces alignment padding.":::
66
+
64 bits of memory are displayed in a row. Starting with the least significant bit, 5 bits are for n Month. The next 8 bits are for n Year. The next 19 bits are unused. The next 3 bits are for n WeekDay. The next 6 bits are for n MonthDay. The remaining bits are unused.
67
+
:::image-end:::
67
68
68
69
The underlying type of a bit field must be an integral type, as described in [Built-in types](../cpp/fundamental-types-cpp.md).
69
70
70
-
If the initializer for a reference of type `const T&` is an lvalue that refers to a bit field of type `T`, the reference is not bound to the bit field directly. Instead, the reference is bound to a temporary initialized to hold the value of the bit field.
71
+
If the initializer for a reference of type `const T&` is an lvalue that refers to a bit field of type `T`, the reference isn't bound to the bit field directly. Instead, the reference is bound to a temporary initialized to hold the value of the bit field.
The `type-id` must be a pointer or a reference to a previously defined class type or a "pointer to void". The type of `expression` must be a pointer if `type-id` is a pointer, or an l-value if `type-id` is a reference.
22
21
23
-
See [static_cast](../cpp/static-cast-operator.md) for an explanation of the difference between static and dynamic casting conversions, and when it is appropriate to use each.
22
+
See [static_cast](../cpp/static-cast-operator.md) for an explanation of the difference between static and dynamic casting conversions, and when it's appropriate to use each.
24
23
25
24
There are two breaking changes in the behavior of **`dynamic_cast`** in managed code:
26
25
27
26
-**`dynamic_cast`** to a pointer to the underlying type of a boxed enum will fail at runtime, returning 0 instead of the converted pointer.
28
27
29
-
-**`dynamic_cast`** will no longer throw an exception when `type-id` is an interior pointer to a value type, with the cast failing at runtime. The cast will now return the 0 pointer value instead of throwing.
28
+
-**`dynamic_cast`** will no longer throw an exception when `type-id` is an interior pointer to a value type; instead, the cast fails at runtime. The cast returns the 0 pointer value instead of throwing.
30
29
31
-
If `type-id` is a pointer to an unambiguous accessible direct or indirect base class of `expression`, a pointer to the unique subobject of type `type-id` is the result. For example:
30
+
If `type-id` is a pointer to an unambiguous accessible direct or indirect base class of `expression`, then a pointer to the unique subobject of type `type-id` is the result. For example:
32
31
33
32
```cpp
34
33
// dynamic_cast_1.cpp
@@ -45,7 +44,7 @@ void f(D* pd) {
45
44
}
46
45
```
47
46
48
-
This type of conversion is called an "upcast" because it moves a pointer up a class hierarchy, from a derived class to a class it is derived from. An upcast is an implicit conversion.
47
+
This type of conversion is called an "upcast" because it moves a pointer up a class hierarchy, from a derived class to a class it's derived from. An upcast is an implicit conversion.
49
48
50
49
If `type-id` is void*, a run-time check is made to determine the actual type of `expression`. The result is a pointer to the complete object pointed to by `expression`. For example:
51
50
@@ -66,7 +65,7 @@ void f() {
66
65
}
67
66
```
68
67
69
-
If `type-id`is not void*, a run-time check is made to see if the object pointed to by `expression` can be converted to the type pointed to by `type-id`.
68
+
If `type-id`isn't `void*`, a run-time check is made to see if the object pointed to by `expression` can be converted to the type pointed to by `type-id`.
70
69
71
70
If the type of `expression` is a base class of the type of `type-id`, a run-time check is made to see if `expression` actually points to a complete object of the type of `type-id`. If this is true, the result is a pointer to a complete object of the type of `type-id`. For example:
72
71
@@ -114,8 +113,9 @@ int main() {
114
113
}
115
114
```
116
115
117
-
 <br/>
118
-
Class hierarchy that shows multiple inheritance
116
+
:::image type="complex" source="../cpp/media/vc39011.gif" alt-text="Diagram that shows multiple inheritance.":::
117
+
The diagram shows a class hierarchy with A as a base class of B which is a base class of D. A is also a base class for C, which is a base class for D. Class D inherits from both B and C.
118
+
:::image-end:::
119
119
120
120
A pointer to an object of type `D` can be safely cast to `B` or `C`. However, if `D` is cast to point to an `A` object, which instance of `A` would result? This would result in an ambiguous casting error. To get around this problem, you can perform two unambiguous casts. For example:
121
121
@@ -137,14 +137,18 @@ void f() {
137
137
138
138
Further ambiguities can be introduced when you use virtual base classes. Consider the class hierarchy shown in the following figure.
139
139
140
-
 <br/>
140
+
:::image type="complex" source="../cpp/media/vc39012.gif" alt-text="Diagram of a class hierarchy that shows virtual base classes.":::
141
+
The diagram shows the classes A, B, C, D, and E arranged as follows: Class A is a base class of B. Classes C and E each derive from B. Class E also inherits from D, which inherits from class B, which inherits from class A.
142
+
:::image-end:::
141
143
Class hierarchy that shows virtual base classes
142
144
143
-
In this hierarchy, `A` is a virtual base class. Given an instance of class `E` and a pointer to the `A` subobject, a **`dynamic_cast`** to a pointer to `B` will fail due to ambiguity. You must first cast back to the complete `E` object, then work your way back up the hierarchy, in an unambiguous manner, to reach the correct `B` object.
145
+
In this hierarchy, `A` is a virtual base class. Given an instance of class `E` and a pointer to the `A` subobject, a **`dynamic_cast`** to a pointer to `B` fails due to ambiguity. You must first cast back to the complete `E` object, then work your way back up the hierarchy, in an unambiguous manner, to reach the correct `B` object.
144
146
145
147
Consider the class hierarchy shown in the following figure.
146
148
147
-
 <br/>
149
+
:::image type="complex" source="../cpp/media/vc39013.gif" alt-text="Diagram of a class hierarchy that shows duplicate base classes.":::
150
+
The diagram shows the classes A, B, C, D, and E arranged as follows: Class B derives from Class A. Class C derives from class A. class D derives from class B. Class E derives from class C, which derives from class A. In this case, the duplicate base class is class A, which is directly or indirectly inherited by all the other classes. Class A is inherited directly by classes B and C, and indirectly by class D via class B, and indirectly by class E via class C, and indirectly in class D via class B.
151
+
:::image-end:::
148
152
Class hierarchy that shows duplicate base classes
149
153
150
154
Given an object of type `E` and a pointer to the `D` subobject, to navigate from the `D` subobject to the left-most `A` subobject, three conversions can be made. You can perform a **`dynamic_cast`** conversion from the `D` pointer to an `E` pointer, then a conversion (either **`dynamic_cast`** or an implicit conversion) from `E` to `B`, and finally an implicit conversion from `B` to `A`. For example:
@@ -165,9 +169,9 @@ void f(D* pd) {
165
169
}
166
170
```
167
171
168
-
The **`dynamic_cast`** operator can also be used to perform a "cross cast." Using the same class hierarchy, it is possible to cast a pointer, for example, from the `B` subobject to the `D` subobject, as long as the complete object is of type `E`.
172
+
The **`dynamic_cast`** operator can also be used to perform a "cross cast." Using the same class hierarchy, it's possible to cast a pointer, for example, from the `B` subobject to the `D` subobject, as long as the complete object is of type `E`.
169
173
170
-
Considering cross casts, it is actually possible to do the conversion from a pointer to `D` to a pointer to the left-most `A` subobject in just two steps. You can perform a cross cast from `D` to `B`, then an implicit conversion from `B` to `A`. For example:
174
+
Considering cross casts, it's possible to do the conversion from a pointer to `D` to a pointer to the left-most `A` subobject in just two steps. You can perform a cross cast from `D` to `B`, then an implicit conversion from `B` to `A`. For example:
171
175
172
176
```cpp
173
177
// dynamic_cast_6.cpp
@@ -186,7 +190,7 @@ void f(D* pd) {
186
190
187
191
A null pointer value is converted to the null pointer value of the destination type by **`dynamic_cast`**.
188
192
189
-
When you use `dynamic_cast < type-id > ( expression )`, if `expression` cannot be safely converted to type `type-id`, the run-time check causes the cast to fail. For example:
193
+
When you use `dynamic_cast < type-id > ( expression )`, if `expression` can't be safely converted to type `type-id`, the run-time check causes the cast to fail. For example:
190
194
191
195
```cpp
192
196
// dynamic_cast_7.cpp
@@ -201,15 +205,15 @@ void f() {
201
205
}
202
206
```
203
207
204
-
The value of a failed cast to pointer type is the null pointer. A failed cast to reference type throws a [bad_cast Exception](../cpp/bad-cast-exception.md). If `expression`does not point to or reference a valid object, a `__non_rtti_object` exception is thrown.
208
+
The value of a failed cast to pointer type is the null pointer. A failed cast to reference type throws a [bad_cast Exception](../cpp/bad-cast-exception.md). If `expression`doesn't point to or reference a valid object, a `__non_rtti_object` exception is thrown.
205
209
206
210
See [typeid](../cpp/typeid-operator.md) for an explanation of the `__non_rtti_object` exception.
207
211
208
212
## Example
209
213
210
214
The following sample creates the base class (struct A) pointer, to an object (struct C). This, plus the fact there are virtual functions, enables runtime polymorphism.
211
215
212
-
The sample also calls a non-virtual function in the hierarchy.
216
+
The sample also calls a nonvirtual function in the hierarchy.
0 commit comments