struct vs class in C++
基本区别
struct 由c语言引入。在c语言中,是定义结构化数据的标准选择。其主观上的定义可参考:https://zh-google-styleguide.readthedocs.io/en/latest/google-cpp-styleguide/classes/#vs
c++ 同时支持struct 和 class. 原因之一是c++ 是 c 的超集,涵盖c 已支持的语言要素,将更好的支持向下兼容(原来能够工作的c 源程序移植到c++,可以支付极少甚至0代价)。首先我们来看结构体在C和C++中的区别。
C语言中的结构体
C语言中的结构体不能为空,否则会报错
要求一个结构或联合至少有一个成员
C语言中的结构体只涉及到数据结构,而不涉及到算法.
也就是说在C中数据结构和算法是分离的。换句话说就是C语言中的结构体只能定义成员变量,但是不能定义成员函数。然而在C++中既可以定义成员变量又可以定义成员函数, C++中的结构体和类体现了数据结构和算法的结合。
不过虽然C语言的结构体中不能定义成员函数,但是却可以定义函数指针,不过函数指针本质上不是函数而是指针,所以总的来说C语言中的结构体只是一个复杂数据类型 ,只能定义成员变量,不能定义成员函数,不能用于面向对象编程。来看一个函数指针的例子:
1 | int FuncAdd(int a, int b) //求和 |
C++语言中的结构体
第一种语法表示
1 | struct 结构体名称{ |
这种方式在声明结构体变量时为:struct 结构体名称 结构体变量名。例如:
1 |
|
第二种语法表示
1 | typedef struct 结构体名称{ |
这种方式在声明结构体变量时有两种方式。
1 | 第一种:struct 结构体名称 构体变量名 |
原因:这里使用了typedef关键字,此关键字的作用就是声明数据类型的别名,方便用户编程,所以这里用了之后,结构体名称别名就相当于struct 结构体名称
。在声明结构体变量时,就无需写struct
了。
1 |
|
第三种方式
1 | struct 结构体名称{ |
相当于:
1 | struct 结构体名称{ |
这种方式既定义了结构体名称,同时声明了一个结构体变量名。在其它地方也可以通过struct 结构体来再次声明其它变量,而第四种方法则不可以。
1 |
|
第四种方式
1 | struct { |
此方式是匿名结构体,在定义时同时声明2个结构体变量,但不能在其它地方声明,因为我们无法得知该结构体的标识符,所以就无法通过标识符来声明变量。
1 |
|
以上C++的四种方式,是同样适用在C中,是对C++对C的结构体的包容。
struct 和 class的区别
struct 和 class 实际在C++ 中没有什么区别。
struct 仍然可以继承自另一个struct (很少看到有人这么干)。
未见任何文档有描述说struct 比 class 更快。个人感觉既然struct 和 class 在实现上可以互换,也就是说要支持相同的语言级基础设施和复杂度,那么就不应该存在用哪个更快的问题。
Struct | Class |
---|---|
字段类型是public, 默认的继承方式也是public | 默认字段类型是private, 默认继承方式也是private。 |
结构体是值类型,它可以包含数据和方法 | 类是引用类型 |
结构体是值类型,不要求堆分配 | |
结构体存储自身的数据在结构体中 | 类存储一个动态对象的引用 |
结构体通常用于较小的数据结构 | 通常较大 |
结构体会影响性能 | |
一个结构体构造函数直接返回结构体值本身(存储在栈的临时位置),该值在必要时被拷贝 | |
对类而言,多个变量可以使用同一个对象的引用 | |
不适用 | 对类而言,对一个变量的操作可能会影响到相同引用的其它变量 |
C语言中的结构体不能为空,否则会报错, 但是C++可以 |
由于struct 和 class 的可替换性,那什么时候用struct,又什么时候用class呢?
答案: 当你需要值语义的时候用 struct,当你需要引用语义的时候就用 class。
值类型 VS 引用类型
这些问题的核心就是数据和数据的存储位置。我们用局部变量、参数、属性和全局变量来存储数据。存储数据有两种最基本的方式。
值类型的变量直接存储数据,而引用类型的变量持有的是数据的引用,数据存储在数据堆中。
值类型(value type):byte,short,int,long,float,double,decimal,char,bool 和 struct 统称为值类型。值类型变量声明后,不管是否已经赋值,编译器为其分配内存。
引用类型(reference type):class统称为引用类型。
值类型的实例通常是在线程栈上分配的(静态分配),但是在某些情形下可以存储在堆中。引用类型的对象总是在进程堆中分配(动态分配)。
C++ 中结构体的继承关系
对于成员访问权限以及继承方式,struct中是public。而class中默认的是private,class还可以用于表示模板类型,struct则不行。
1 | namespace std{ |
另外namespace std{} : 称namespace(命名空间),在声明一个命名空间时,花括号内不仅可以包括变量,而且还可以包括以下类型:
- 变量(可以带有初始化);
- 常量;
- 数(可以是定义或声明);
- 结构体;
- 类;
- 模板;
C++类的定义和实现
定义(默认的是private):
1 | class 类名 |
实现
两种方式:一种类内 实现(setPoint),另外一种是在类内对成员函数进行声明 ,类外实现(setPoint2)
1 |
|
总结
概念:class和struct的语法基本相同,从声明到使用,都很相似,但是struct的约束要比class多,理论上,struct能做到的class都能做到,但class能做到的stuct却不一定做的到。
类型:struct是值类型,class是引用类型,因此它们具有所有值类型和引用类型之间的差异。
效率:由于堆栈的执行效率要比堆的执行效率高,但是堆栈资源却很有限,不适合处理逻辑复杂的大对象,因此struct常用来处理作为基类型对待的小对象,而class来处理某个商业逻辑。
关系:struct不仅能继承也能被继承 ,而且可以实现接口,不过Class可以完全扩展。内部结构有区别,struct只能添加带参的构造函数,不能使用abstract和protected等修饰符,不能初始化实例字段。