2020-C++高级程序设计-C++ Union

Union

  1. 共享存储空间(三选一!)
1
2
3
4
5
6
union user{
//从以下三个情况选择一种
int ival;
double dval;
char cval;
}

1. 统一数据空间用两种操作方式进行操作

  1. 常用于系统软件和嵌入式系统
  2. 例子(将数组组合成矩阵)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
double  _element[3][3];
int i, j;
for (i=0;i<3;i++)
for (j=0;j<3;j++)
_element [i][j] = (i+1)*(j+1);

for ( i=0;i<3;i++){
for ( j=0;j<3;j++)
cout << _element [i][j] << " ";
cout << endl;
}
union Matrix{
struct
{ double _a11, _a12, _a13;
double _a21, _a22, _a23;
double _a31, _a32, _a33;
};
double _element[3][3];
};
//如果没有struct,那么布局会出现问题
Matrix m;
int i, j;
for (i=0;i<3;i++)
for (j=0;j<3;j++)
m._element[i][j] = (i+1)*(j+1);
//每个单元都有两个名称

for ( i=0;i<3;i++){
for ( j=0;j<3;j++)
cout << m._element[i][j] << " ";
cout << endl;
}

2. Union的另一种用法

  1. 例:定义数组, 存储100个图形(直线、矩形、圆)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
struct Line{
int x1, y1, x2, y2
};
struct Ellipse{
int x, y, r;
};
struct Rectangle{
int lef, top, rig, bot;
}
//第一种实现
Line figures_L[100];
Rectangle figures_R[100];
Ellipse firgures_E[100];
//过于浪费空间
//第二种实现
enum FIGURE_TYPE {LINE, RECTANGLE, ELLIPSE};//使用标签来确认其类别
struct Line{
FIGURE_TYPE t ;
int x1, y1, x2, y2;
};
struct Ellipse{
FIGURE_TYPE t;
int x, y, r;
};
struct Rectangle{
FIGURE_TYPE t;
int left, top, rig, bot;
}
union FIGURE{
FIGURE_TYPE t;//共享了第一块空间
Line line;
Rectangle rect;
Ellipse ellipse;
};

FIGURE figures[100];
void main()
{ input( figures, 100 );
for (int i=0;i<100;i++)
draw(figures[i]);
}

//API:
void draw_line(int,int,int,int);
void draw_rect(int,int,int,int);
void draw_ellipse(int,int,int);
  1. Union占据的空间:
  • 选中最大的空间进行共享
  • 注意最右边的t,这方便了我们的访问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//多态性
void draw(FIGURE figure){
switch ( figure.t ){
case LINE:
draw_line(figure.line.x1, ……);
break;
case RECTANGLE:
draw_rect(figure.rect.lef, ……);
break;
case ELLIPSE:
draw_ellipse(figure.ellipse.x, ……);
break;
}
}
void input (Figure fig[], int size){
int t;
for (int k=0; k<size; k++){
cin >> t;
switch (t){
case LINE:
fig[k].type = LINE;
cin >> fig[k].line.x1 >> fig[i].line.y1 >> fig[k].line.x2 >> fig[i].line.y2;
break;
case RECTANGLE: ……
case ELLIPSE: …….
}
}
}
  1. 如果要增加color和width
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
enum FIGURE_TYPE  {LINE, RECTANGLE, ELLIPSE};//使用标签来确认其类别
struct Line{
FIGURE_TYPE t ;
int color, int width;
int x1, y1, x2, y2;
};
struct Ellipse{
FIGURE_TYPE t;
int color, int width;
int x, y, r;
};
struct Rectangle{
FIGURE_TYPE t;
int color, int width;
int left, top, rig, bot;
}
union FIGURE{
FIGURE_TYPE t;//共享了第一块空间
int color, int width;
Line line;
Rectangle rect;
Ellipse ellipse;
};

  1. C++不希望在运行时进行类型检查
  • 所有C++利用virtual func来进行实现

3. 互斥赋值

  1. 在任何时刻,联合中只能有一个数据成员可以有值。当给联合中某个成员赋值之后,该联合中的其他成员就会变成为赋值状态

4. 结构和联合

  1. 通过使用union完成和保证c++运行时的多态性

5. 参考

C++ 关于union的理解


2020-C++高级程序设计-C++ Union
https://spricoder.github.io/2020/07/01/2020-C-plus-plus-advanced-programming/C++-%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/2020-C-plus-plus-advanced-programming-C++%20Union/
作者
SpriCoder
发布于
2020年7月1日
许可协议