Type aliases (typedef / using)
In C++, any valid type can be aliased so that it can be referred to with a different identifier.
//using new_type_name = existing_type ;
using C = char;
using WORD = unsigned int;
using pChar = char *;
using field = char [50];
Both aliases defined with typedef
and aliases defined with using
are semantically equivalent. The only difference being that typedef
has certain limitations in the realm of templates that using
has not. Therefore, using
is more generic, although typedef
has a longer history and is probably more common in existing code.
Unions
Unions allow one portion of memory to be accessed as different data types.
union type_name { member_type1 member_name1; member_type2 member_name2; member_type3 member_name3; . . } object_names;
This creates a new union type, identified by type_name
, in which all its member elements occupy the same physical space in memory. The size of this type is the one of the largest member element. For example:
union mytypes_t {
char c;
int i;
float f;
} mytypes;
declares an object (mytypes
) with three members:
mytypes.c
mytypes.i
mytypes.f
For example:
union mix_t {
int l;
struct {
short hi;
short lo;
} s;
char c[4];
} mix;
If we assume that the system where this program runs has an int
type with a size of 4 bytes, and a short
type of 2 bytes, the union defined above allows the access to the same group of 4 bytes: mix.l
, mix.s
and mix.c
, and which we can use according to how we want to access these bytes: as if they were a single value of type int
, or as if they were two values of type short
, or as an array of char
elements, respectively. The example mixes types, arrays, and structures in the union to demonstrate different ways to access the data. For a little-endian system, this union could be represented as:
---------------------------------------------------------------------------------------------------------------------------------
Anonymous unions
When unions are members of a class (or structure), they can be declared with no name. In this case, they become anonymous unions, and its members are directly accessible from objects by their member names. For example, see the differences between these two structure declarations:
The only difference between the two types is that in the first one, the member union has a name (price
), while in the second it has not. This affects the way to access members dollars
and yen
of an object of this type. For an object of the first type (with a regular union), it would be:
book1.price.dollars
book1.price.yen
whereas for an object of the second type (which has an anonymous union), it would be:
book2.dollars
book2.yen
Again, remember that because it is a member union (not a member structure), the members dollars
and yen
actually share the same memory location, so they cannot be used to store two different values simultaneously. The price
can be set in dollars
or in yen
, but not in both simultaneously.
------------------------------------------------------------------------------------------------------------------------------
Enumerated types (enum)
Enumerated types are types that are defined with a set of custom identifiers, known as enumerators, as possible values. Objects of these enumerated types can take any of these enumerators as value.
Their syntax is:
enum type_name {
value1,
value2,
value3,
.
.
} object_names;
For example,
#include <iostream>
using namespace std;
int main()
{
enum colors_t { black, blue, green, cyan, red, purple, yellow, white };
colors_t mycolor;
mycolor = blue;
if (mycolor == green) mycolor = red;
cout << mycolor << endl; //output: 1 因为blue在1的位置啊
return 0;
}
//如果mycolor = green 这个程序的ouput就变成了 4 。因为根据程序最后Mycolor=red 了,而red是第四个位置
A specific integer value can be specified for any of the possible values in the enumerated type. And if the constant value that follows it is itself not given its own value, it is automatically assumed to be the same value plus one. For example:
enum months_t { january=1, february, march, april,
may, june, july, august,
september, october, november, december} y2k;
---------------------------------------------------------------------------------------------------------------------------------
Enumerated types with enum class
in C++, it is possible to create real enum
types that are neither implicitly convertible to int
and that neither have enumerator values of type int
, but of the enum
type itself, thus preserving type safety. They are declared with enum class
(or enum struct
) instead of just enum
:
enum class Colors {black, blue, green, cyan, red, purple, yellow, white};
Each of the enumerator values of an enum class type needs to be scoped into its type (this is actually also possible with enum types, but it is only optional). For example:
Colors mycolor;
mycolor = Colors::blue;
if (mycolor == Colors::green) mycolor = Colors::red;
Enumerated types declared with enum class
also have more control over their underlying type; it may be any integral data type, such as char
, short
or unsigned int
, which essentially serves to determine the size of the type. This is specified by a colon and the underlying type following the enumerated type. For example:
enum class EyeColor : char {blue, green, brown};