类和结构
在我们理解Class和Struct之间的区别之前,我们应该知道一些与它们相关的基本概念。如果不理解概念,就很难理解两者之间的差异。
什么是类和对象:
这些是与面向对象编程相关的两个重要概念,它们构成了将函数和数据传递给其他函数的基础。为了更好地理解,我们可以将它与现实生活中的例子联系起来。类可以被视为商店,而对象可以是任何单独的特定商店,例如杂货店,文具,水果等。所有对象共享主类的共同属性 - 商店 - 反过来,对象可能有自己的专有属性,如特定的设计,灯光等。通过对象,我们实际上可以使用该类;它们构成了一个类的实例。
类的语法
Class Store {
公共字符串;
公共字符串设计;
}
对象的语法
Store grocery = new Store();
Store Stationery = new Store();
什么是结构?
Struct仅包含数据,因此有助于通过Struct对象构建各个数据要求。与课程不同,它缺乏功能。这是它的语法:
struct grocery_entrance {
char entrance_name [50];
int entrance_size;
} grocery_entrance;
所有商店都可以使用具有个人名称和尺寸的Struct'入口'。
什么是继承?
它类似于儿子如何继承他父亲的财产,反过来,儿子也可以添加他自己的其他财产。 Class可以是基类,也可以是派生类,前者可以作为后者的基础。派生类除了从基类获取的内容外,还为自己添加了一些其他属性。当我们考虑上面的例子时,杂货店仍然可以派生到特定的杂货店,例如XYZ杂货店。
既然我们熟悉了基本概念,我们就可以了解Class和Struct之间的实际区别。
他们如何不同?
- 可重用性: 由于Classes构成了基本框架,因此可以重复使用;但是,结构是具有特定属性的单个元素,因此不能重复使用。例如,杂货店Class可用于任何类型的杂货店,但Struct grocery_entrance仅针对该杂货店而且在其他类中重复使用它没有意义。
- 能见度: 类中的所有函数都可以在其对象中公开使用。例如,我们在Class'store'下有一个名为'things'的函数。函数'things'对所有对象都是可见的,例如'杂货店','文具店'等。对于Structs,这种可见性是不可能的,因为struct的数据仅限于自身,而其他Structs不可见。为了清楚说明,我们可以说'grocery_entrance'的数据并非对所有其他商店公开可见。
- 通过参考并通过价值: “按引用传递”仅将内存位置而不是实际数据发送到函数。这意味着每当值发生变化时,更改都会反映在相应的函数中。反过来,传递值只是将值发送给函数。在这种情况下,发送后的值的更改将不会反映在该函数中。类使用按引用传递,而Struct使用传递值。
- 遗产: 可以进一步继承类以形成子类,但Structs不能使用继承。例如,Class Store将其功能赋予子类“杂货店”。但结构'grocery_entrance'不能继承任何功能。我们可以说这里没有子结构这样的概念。
- 默认可见性: 默认情况下,类的所有成员都保留为私有实体,而Struct的成员默认保留为公共实体。
- 空类和结构的大小: 即使它是空的,Class也使用1 Byte的大小,而当它为空时,Struct从不使用任何内存。这意味着我们可以说空结构的大小等于0字节。
- 垃圾收集: 可以使用Classes进行垃圾收集,因为它们使用pass by reference。因此,在存储数据的一个位置更容易进行清理。另一方面,Struct不能进行垃圾收集,因为它使用pass by value并且数据分散在不同的位置。
- 内存管理: 因为Class允许垃圾收集,所以内存管理也很有效;然而,它对Structs来说并不那么有效。
- 构造函数: 构造函数通常使用某些指定值初始化类。我们可以把它看作是用值初始化的东西。如果必须创建新类,则调用构造函数为该实例分配内存。我们甚至可以在调用构造函数时将值作为参数传递。现在让我们进行实际讨论。类允许所有类型的构造函数,例如带或不带参数,而结构只允许带有参数的构造函数,即参数化构造函数。
- 析构函数: 每当我们需要删除类的实例时,就会调用析构函数。反过来,析构函数会删除该实例并释放内存。 Class可以使用析构函数,而Struct则不能。
- 成员变量初始化: 在Classes中,我们可以直接初始化成员变量; Structs无法进行这样的初始化。
- 对象创建: 类中对象创建的一般语法是:
Demo obj = new Demo();
这意味着我们必须在创建类的对象时使用关键字“new”。创建Structs的对象时不需要这样做。只需看看他们的语法:
演示obj;
即使没有关键字“new”,它也能完美运行。
何时使用类以及何时使用Struct?
由于类在处理数据和函数时更加灵活,因此当使用的对象复杂且庞大时,我们可以使用它。在我们的示例中,Mall可以使用“store”类以更好的方式表达系统。但是,结构仅限于较小的对象,因为它们的效率相对低于类。因此,如果您设计自己的商店,Structs是更好的选择。
如何将结构转换为类和反之亦然?
您可能听说过“装箱”和“取消装箱”这两个术语,可以将Struct转换为Class,反之亦然。虽然这些是帮助我们进行转换的有效流程,但应谨慎处理。由于这会直接影响内存位置,因此会对系统性能产生巨大影响。此外,它会影响垃圾收集过程并导致整个系统效率低下。因此,仅在需要时才使用这些转换。
让我们以表格形式来看上述差异。
S.No | 概念 | 差异 | |
类 | 结构 | ||
1 | 可重用性 | 完全可重复使用 | 不可重复使用 |
2 | 能见度 | Class的所有函数对其对象都是可见的 | 结构的对象的数据对于同一Struct的其他对象不可见 |
3 | 通过参考传递并通过价值传递 | 使用Pass by Reference | 使用Pass by Value |
4 | 遗产 | 类的功能可以由其子类继承;允许继承 | 永远不允许继承 |
5 | 默认可见性 | 默认情况下,类的所有成员都是私有的 | Struct的所有成员默认都是公共的 |
6 | 空的大小 | 空类的大小是1字节 | 空Struct的大小为0字节 |
7 | 垃圾收集 | 因为它使用传递引用,所以可以进行垃圾收集 | 由于它使用pass by value,因此无法进行垃圾回收 |
8 | 内存管理 | 垃圾收集过程的简易性有助于有效的内存管理 | 垃圾收集的缺乏导致内存管理不善 |
9 | 构造函数 | 允许所有类型的构造函数,例如带或不带参数 | 仅允许参数化构造函数 |
10 | 析构函数 | 可以用它 | 不能用它 |
11 | 成员变量初始化 | 允许直接初始化成员变量 | 不允许成员变量的直接字初始化 |
12 | 对象创建 | 在对象创建期间必须使用关键字“new” | 在对象创建期间使用关键字“new”是可选的 |
13 | 何时使用? | 更适合需要继承的大型和复杂对象 | 对于较小和较简单的对象更好,其中继承不太重要。 |
我们几乎涵盖了Class和Struct之间的所有差异,如果您觉得缺少某些东西,请告诉我们。让我们一起学习,充分利用这些知识!