C++—17、C++ 中的类和结构体的区别

news/2025/1/19 6:23:37/

一、类和结构体的区别如下:

1、类的成员默认是private私有的

(1)错误的为:

#include <iostream>
#define LOG(x) std::cout << x << std::endl;
class player
{int x, y;//如果我没有声明它是public,那么默认是privateint speed;void move(int xa, int ya) {x += xa * speed;y += ya * speed;}
};
void main()
{player player;player.move(1, 1);//方法无法访问类的私有变量x,y。}

当运行时会出现以下2个错误提示:

错误一:函数 “player::move”: 不可访问 

错误二: “player::move”:无法访问private成员

(2)错误的为:

因为move方法默认是私有的private,只有类的内部的其它方法才能访问move。

(3)正确的应为:

所以当我们在player类的外面调用move方法时,一定要在前面加上public。

#include <iostream>
#define LOG(x) std::cout << x << std::endl;
class player
{
public:void move(int xa, int ya)//如果我没有声明它是public,那么默认是private{x += xa * speed;y += ya * speed;}
private:int x, y;//如果我没有声明它是public,那么默认是privateint speed;};
int main()
{player player;player.move(1, 1);
}

(4)正确的

所以如果你没有指定任何类型的可见修饰符,类的成员是不可见的。或者你没有指定任何内容,默认就会是私有的。

2、struct默认是公有的public

通过这个实例可以看出struct成员默认是公有的,我们修改下代码,看看是不是出现一样的错误:

只要注明公有或者私有,还未看出来有什么区别。

二、类和结构体的使用情况说明

类和结构体作用上说它们确实没有太大区别,但是在代码实际使用时确实有所不同,在c++中结构体存在的唯一原因是它想要维持与c之间的兼容性,因为c中没有类然而它有结构体,如果我们突然彻底删除struct这个关键字,那样我们就会降低它们的兼容性。因为C++编译器不知道什么是struct。当然你可以通过使用#很容易修复它,我们可以写上类似#define struct class的语句,这样就瞬间完成了所有struct替换成了class。我们来尝试下。

struct换成class后,出现了前面的问题,声明为public就可以了。

到底啥时候用它们,只能从语义上或者如何看待它。如果我想成员全部公开并且不想写public就用struct;当谈论一些plain old data(pod)或者只是包含一些变量的结构时,可以用struct,一个很好的例子可能是数学中的向量类。

(在C++中,POD类型(Plain Old Data)是一个概念,用来指代那些与C语言的结构和数据类型兼容的类或结构体。POD类型的对象可以通过内存复制(如使用std::memcpy)来进行复制和序列化,并且保证复制后的对象状态是有效的。POD类型的对象在内存中具有连续的、可预测的布局,这使得它们非常适合用于与硬件、网络通讯或与C语言库的接口。)

例如,我想要定义一个结构,将两个浮点数放在一起,比如说vec2,我把它定义为一个struct,里面只有两个浮点数x和y。从根本上说这个vec2不管是用struct还是class又或者其他类型,都只是代表两个浮点数的一种数据结构。它不应该像player类那样包含大量的功能,一个player类,可能有一个3D模型,它可能会为这个3D模型处理渲染代码。它可能处理一些,像玩家在地图上如何移动、接受键盘的输入等。这里面有太多的功能。这里它仅仅是将两个变量结合起来。只是为了使我们的代码易于使用。这就是我们做的全部。当然这不是说我不打算在里面添加方法。我绝对会的,我可能会添加一个叫做add的方法,该方法接受另外一个Vec2,然后像这样将它和目前的向量相加。这里做的只是操纵这些变量,只是添加了一个可以操作这些变量的函数,如下:

struct vec2
{
    float x, y;
    void add(const vec2& other)
    {
        x += other.x;
        y += other.y;
    }
};

到最后,我还是谈论这两个变量。

如果需要继承,绝对不会对struct使用继承,如果我真的要用一个完整的类层次或某种继承层次的结构,将会使用class。因为继承又增加了另一层复杂性,而我希望我的结构体仅仅是数据的结构体。

三、总结

结构体用来表示一些数据,class用来使用作为很多功能的类,例如玩家,或者其他可能继承的东西。两者除了可见性之外没有什么区别。

1、主要区别

  • 默认访问权限:结构体的成员默认为公有,而类的成员默认为私有。

  • 继承:当结构体继承时,默认为公有继承;而类默认为私有继承,除非显式指定为公有或受保护继承。

  • 成员函数:结构体可以有成员函数,但通常用于简单的数据操作;类的成员函数可以更复杂,支持封装和抽象。

  • 构造函数和析构函数:类可以有构造函数和析构函数,用于对象的初始化和清理;结构体也可以有,但通常用于简单的数据封装。

2、使用场景

  • 结构体:适用于存储和管理简单的数据集合,例如,当需要将数据打包和传递时,或者当数据的组织比行为更重要时。

  • :适用于需要封装数据和行为的场景,特别是在面向对象编程中,用于建模具有复杂行为的实体。

在实际编程中,选择使用结构体还是类取决于具体的需求和设计目标。虽然结构体和类在语法上非常相似,但它们在访问控制、继承和成员函数方面的默认行为有所不同,这些差异决定了它们各自最适合的使用场景。


http://www.ppmy.cn/news/1564330.html

相关文章

二手车交易系统的设计与实现(代码+数据库+LW)

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统二手车交易信息管理难度大&#xff0c;容错率低&#xf…

PostgreSQL-WAL日志介绍(一)

1. 概述 1.1 WAL日志 WAL日志&#xff1a;即预写式日志&#xff08;Write-Ahead Logging&#xff09;&#xff0c;是保证数据完整性、实现事务日志的一种标准方法。WAL的中心思想是数据文件的修改必须在这些动作被日志记录后才被写入&#xff0c;即先写日志&#xff0c;再写数…

反转字符串中的单词 II:Swift 实现与详解

网罗开发 &#xff08;小红书、快手、视频号同名&#xff09; 大家好&#xff0c;我是 展菲&#xff0c;目前在上市企业从事人工智能项目研发管理工作&#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术&#xff0c;包括iOS、前端、Harmony OS、Java、Python等…

React实现拖拽特效

前言 最近&#xff0c;我看到一个工程师的个人网站上&#xff0c;采用了拖拽作品集的互动特效&#xff0c;既有趣又吸引眼球。经过一些研究&#xff0c;我发现其实借助一些现成的套件&#xff0c;就能轻松实现这样的效果。今天就带大家一起看看&#xff0c;如何通过 Framer Mo…

提示词的艺术----AI Prompt撰写指南(个人用)

提示词的艺术 写在前面 制定提示词就像是和朋友聊天一样&#xff0c;要求我们能够清楚地表达问题。通过这个过程&#xff0c;一方面要不断练习提高自己地表达能力&#xff0c;另一方面还要锻炼自己使用更准确精炼的语言提出问题的能力。 什么样的提示词有用&#xff1f; 有…

阻塞赋值和非阻塞赋值

理论学习 阻塞赋值 用 表示 &#xff0c;这种对应的电路结构常常与触发器没有关系&#xff0c;只与输入电平的变化有关系。可以将阻塞赋值的操作看作只有一个步骤的操作&#xff0c;即将计算赋值符号的右边赋值给左边&#xff0c;在未执行完之前&#…

设计模式(4)行为模式

行为模式 1. Chain of Responsibility Pattern&#xff08;责任链模式&#xff09;2.Command Pattern&#xff08;命令模式&#xff09;3.Interpreter Pattern&#xff08;解释器模式&#xff09;▲4.Iterator&#xff08;迭代器模式&#xff09;5.Mediator&#xff08;中介者模…

机器学习-基本术语

文章目录 1. **数据集&#xff08;Dataset&#xff09;**2. **样本&#xff08;Sample&#xff09;**3. **属性&#xff08;Attribute&#xff09;**4. **特征&#xff08;Feature&#xff09;**5. **属性值&#xff08;Attribute Value&#xff09;**6. **属性空间&#xff08…