C++ union、struct 和 class

这一篇介绍一下 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编译器下进行的

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值