这一篇介绍一下 C++ 中 union、struct 和 class 的异同点
如有侵权,请联系删除,如有错误,欢迎大家指正,谢谢
union
- 联合的所有成员有共享内存空间的特性,即联合所有的成员内存起始地址都是相同的,在初始化的时候只初始化一个成员就够了,在联合的初始化列表中只有一个初始化器(写多了会报错),如果不指定要初始化的元素,默认是初始化第一个成员
#include <iostream>
using namespace std;
union Un {
int a;
char c[4];
}un1 = { 134480385 }, un2{ 134480385 }, un3;
int main() {
Un un4 = { 134480385 };
Un un5{ 134480385 };
Un un6;
system("pause");
return 0;
}
- 联合的定义可以在联合的结尾处在 “;” 前定义,也可以通过联合的名字定义
- 联合的初始化也可以用 C++11 的统一初始化方式
- 在初始化时,如果是全局变量,系统会自动初始化为0,通过初始化列表进行初始化时,如果被初始化的元素内存小于联合占有的内存,未初始化的部分默认是0,与数组类似,并且联合也符合内存对齐的原则,主要是要符合内存对齐中规则3,在未指定对齐大小时,联合所占内存大小是联合中最大元素的整数倍,如果指定了对齐大小(#pragam pack(n)),联合的大小时n的整数倍
struct
C++ 和 C 中 struct 的异同
- C++ 中引入 struct 是为了兼容 C,C++ 对结构体进行了一些扩充
- C++ 中 struct 可以有成员函数(构造函数、析构函数、常规函数和虚函数)、静态成员(静态成员函数和静态成员变量),C 中不可以
// ====== Cpp文件 ======
struct Test {
public:
Test(int n) // 构造函数
: n(n) {
}
virtual void vfunc() { // 虚函数
cout << n << " " << sn << endl;
}
static void sfunc() { // 静态函数
cout << sn << endl;
}
~Test() { } // 析构函数
private:
int n;
static int sn; // 静态数据成员
};
int Test::sn = 10; // 与类中静态数据成员一样,也需要在结构体外初始化
Test(5).vfunc(); // 运行结果:5 10
Test::sfunc(); // 运行结果:10
- C++ 中 struct 可以继承 struct 和 class 或者 被 struct 和 class 继承,C 不可以
- C++ 中 struct 有 public、protected 和 private 不同的访问修饰,默认是 public,C 只有默认的 public,不能修改
- C++ 中声明结构体变量可以直接用结构体名字,C 声明结构体变量必须在结构体名字前面加上 struct
struct S {
int n;
double d;
};
S s1; // C++ 定义结构体变量
struct S s2; // C 定义结构体变量,C++ 也可以这样定义
- C++ 中可以声明空结构体,C 不可以
C++ 中 struct 和 class 的异同
- struct 默认访问属性是 public,class 默认访问属性是 private
- struct 继承 struct 或 class 默认是 public 继承,class 继承 struct 或 class 默认是 private 继承,换句话说,子类的默认继承属性取决于子类而不是父类
// ====== 测试一 ======
struct STest1 {
int n;
};
STest1 sTest;
sTest.n = 10; // 默认是 public
// ====== 测试二 ======
class CA {
public:
int cAn;
};
struct SA {
public:
int sAn;
};
struct STest1 : CA { };
struct STest2 : SA { };
class CTest1 : CA { };
class CTest2 : SA { };
STest1 sTest1;
sTest1.cAn = 10; // struct 继承 class 默认继承属性是 public
STest2 sTest2;
sTest2.sAn = 10; // struct 继承 struct 默认继承属性是 public
CTest1 cTest1;
cTest1.cAn = 10; // class 继承 class 默认继承属性是 private,这里会报错
CTest2 cTest2;
cTest2.sAn = 10; // class 继承 struct 默认继承属性是 private,这里会报错
- struct 不可用于定义泛型编程中的模板参数,class 可以用于定义泛型编程中的模板参数(与 typename相同)
- C++ 中若 strcut 仅作为数据类型的集合,可以使用 “{ }” 进行初始化,若加上构造函数或虚函数将不能再用 “{ }” 进行初始化,构造函数的作用便是对 struct 或 class 进行出初始化操作,故 struct 中含有构造函数就不能用 “{ }” 进行初始化,struct 用 “{ }” 初始化是按照数据在内存中的顺序从起始地址依次初始化的,struct 含有虚函数后,struct 的起始地址首先是虚指针,故不能再用 “{ }” 进行初始化
注意
- struct 全部初始化时,在 “{ , , , }” 中将全部要初始化成员的值依次写入,对成员进行初始化
- 对全局结构体变量而言,如果不对其进行初始化,系统将把其成员全部初始化为0,这也是全局变量的特点,对于结构体变量同样是适用的
- 对于定义在函数体内部的局部变量,系统不会对其进行自动初始化,其成员为随机值
- 另外还可以进行部分初始化,未初始化的部分系统默认初始化为0(全局和局部变量都适用),与数组相同
参考文章
[1] C++中Struct与Class的区别与比较
如果未特殊说明,以上测试均是在win10 vs2017 64bit编译器下进行的