c++ 中 class 和 struct 的区别是什么

2023-05-16



C++中的struct对C中的struct进行了扩充,它已经不再只是一个包含不同数据类型的数据结构了,它已经获取了太多的功能。
struct能包含成员函数吗? 能!
struct能继承吗? 能!!
struct能实现多态吗? 能!!!
 

既然这些它都能实现,那它和class还能有什么区别?

最本质的一个区别就是默认的访问控制: 

默认的继承访问权限

struct是public的class是private的
你可以写如下的代码:
struct A
{
  char a;
};
struct B : A
{
  char b;
};

这个时候B是public继承A的。

如果都将上面的struct改成class,那么B是private继承A的。这就是默认的继承访问权限。 

所以我们在平时写类继承的时候,通常会这样写:
class B : public A

就是为了指明是public继承,而不是用默认的private继承。

 

当然,到底默认是public继承还是private继承取决于子类而不是基类

我的意思是,struct可以继承class,同样class也可以继承struct,那么默认的继承访问权限是看子类到底是用的struct还是class。如下:

 

struct A{};class B : A{}; //private继承
struct C : B{}; //public继承

 

struct作为数据结构的实现体,它默认的数据访问控制是public的,而class作为对象的实现体,它默认的成员变量访问控制是private的

 

我依旧强调struct是一种数据结构的实现体,虽然它是可以像class一样的用。我依旧将struct里的变量叫数据,class内的变量叫成员,虽然它们并无区别。


到底是用struct还是class,完全看个人的喜好,你可以将程序里所有的class全部替换成struct,它依旧可以很正常的运行。但我给出的最好建议,还是:当你觉得你要做的更像是一种数据结构的话,那么用struct,如果你要做的更像是一种对象的话,那么用class。 

当然,我在这里还要强调一点的就是,对于访问控制,应该在程序里明确的指出,而不是依靠默认,这是一个良好的习惯,也让你的代码更具可读性。 

说到这里,很多了解的人或许都认为这个话题可以结束了,因为他们知道struct和class的“唯一”区别就是访问控制。很多文献上也确实只提到这一个区别。 

但我上面却没有用“唯一”,而是说的“最本质”,那是因为,它们确实还有另一个区别,虽然那个区别我们平时可能很少涉及。

那就是:“class”这个关键字还用于定义模板参数,就像“typename”。但关键字“struct”不用于定义模板参数。这一点在Stanley B.Lippman写的Inside the C++ Object Model有过说明。 

问题讨论到这里,基本上应该可以结束了。但有人曾说过,他还发现过其他的“区别”,那么,让我们来看看,这到底是不是又一个区别。还是上面所说的,C++中的struct是对C中的struct的扩充,既然是扩充,那么它就要兼容过去C中struct应有的所有特性。例如你可以这样写: 

struct A //定义一个struct
{
   char c1;
   int n2;
   double db3;
};
A a={'p', 7, 3.1415926}; //定义时直接赋值
 

也就是说struct可以在定义的时候用{}赋初值。那么问题来了,class行不行呢?将上面的struct改成class,试试看。报错!噢~于是那人跳出来说,他又找到了一个区别。我们仔细看看,这真的又是一个区别吗? 

你试着向上面的struct中加入一个构造函数(或虚函数),你会发现什么?
对,struct也不能用{}赋初值了
的确,以{}的方式来赋初值,只是用一个初始化列表来对数据进行按顺序的初始化,如上面如果写成A a={'p',7};则c1,n2被初始化,而db3没有。这样简单的copy操作,只能发生在简单的数据结构上,而不应该放在对象上。加入一个构造函数或是一个虚函数会使struct更体现出一种对象的特性,而使此{}操作不再有效。 

事实上,是因为加入这样的函数,使得类的内部结构发生了变化。而加入一个普通的成员函数呢?你会发现{}依旧可用。其实你可以将普通的函数理解成对数据结构的一种算法,这并不打破它数据结构的特性。 

那么,看到这里,我们发现即使是struct想用{}来赋初值,它也必须满足很多的约束条件,这些条件实际上就是让struct更体现出一种数据机构而不是类的特性。 

那为什么我们在上面仅仅将struct改成class,{}就不能用了呢?

其实问题恰巧是我们之前所讲的——访问控制!你看看,我们忘记了什么?对,将struct改成class的时候,访问控制由public变为private了,那当然就不能用{}来赋初值了。加上一个public,你会发现,class也是能用{}的,和struct毫无区别!!! 

做个总结,从上面的区别,我们可以看出,struct更适合看成是一个数据结构的实现体,class更适合看成是一个对象的实现体。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++ 中 class 和 struct 的区别是什么 的相关文章

  • 零基础视觉SLAM(一)

    文章目录 SLAM简介什么是SLAM xff1f 传感器VSLAM架构视觉里程计后端优化 SLAM应用自学参考书预备知识 SLAM简介 什么是SLAM xff1f SLAM从本质上来说它要实现的就是通过传感器去实时地估计自身位置及经过的轨迹
  • 关于Proxmox 5.x的国内有效镜像源

    官网的 http download proxmox com 有多慢我就不提了 xff0c 否则大家也不会看到这篇小文 首先需要分清楚Proxmox VE的镜像构成 1 xff09 Debian自身 这个用国内哪个镜像都可以 xff0c al
  • 多线程是否真的有必要?

    一点疑问 相比大家在投简历 面试等等过程中 xff0c 或多或少会遇到这么一个问题 xff1a 熟悉掌握多线程开发 xff1b 谈谈你对多线程的认识 其实 xff0c 我有这么一个疑问 xff0c 那就是多线程真的有必要么 xff1f 根据
  • stm32无法烧录问题分析

    1 开始能烧录 xff0c 烧录程序后就不能烧录了 原因 xff1a 升级接口IO被代码修改应用 xff0c 导致无法烧录 xff0c 解决办法 xff1a 可以让MCU进入升级模式 xff08 拉高boot0 xff0c 然后复位MCU
  • 【Git】msysgit + TortoiseGit:在 windows 上安装配置版本控制工具 Git 图形化使用

    msysgit 43 TortoiseGit xff1a 在 windows 上安装配置版本控制工具 Git 图形化使用 一 安装说明 Git 是 Linux Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控
  • Slickedit使用记录

    Slickedit使用记录 一 快捷键二 问题和解决方法 一 快捷键 已经习惯了android studio 中的快捷键 xff0c 在slickedit上也做下修改Tools gt options gt Keyboard and mous
  • 查看.Net源代码vs版本号

    方法 xff1a 用记事本打开vs项目的 sln文件 第2行就是这个源代码包的开发软件vs版本号了 Microsoft Visual Studio Solution File Format Version 9 00 Visual Studi
  • Docker: GUI 应用,Ubuntu 上如何运行呢?

    操作系统 Ubuntu 18 04运行镜像 continuumio anaconda3 based on debian Step 1 安装 Docker span class token comment update the apt pac
  • 网络爬虫详细设计方案

    目录 网络爬虫设计方案 1 网络爬虫简介 2 Java爬虫的开发和使用流程 2 1 下载 2 2 分析 3 单点登陆与Jsoup解析 3 1 单点登陆简介 3 1 1 登陆 3 1 2 注销 3 2 Jsoup网页解析 4 网络爬虫详细设计
  • 安装 python-dev 的时候,缺少依赖关系

    sudo aptitude install python dev报错 xff1a 下列软件包有未满足的依赖关系 xff1a python dev 依赖 libpython dev 61 2 7 5 5ubuntu3 但是它将不会被安装 依赖
  • maven-replacer-plugin 静态资源打包方案js css

    解决问题 xff1a 防止浏览器缓存 xff0c 修改js css后无效 xff0c 需要强刷 两种解决方案 xff1a 1 不依赖插件 xff0c 纯代码实现 1 1 实现拦截处理器 xff1a ModelAndViewIntercept
  • 简单FTP构建及访问

    使用2台RHEL6虚拟机 xff0c 其中一台作为vsftpd服务器 xff08 192 168 4 5 xff09 另外一台作为测试用的Linux客户机 xff08 192 168 4 205 xff09 在RHEL6系统中 xff0c
  • freertos程序死机原因

    一 开机死机原因 1 一般是某任务栈溢出所致 栈溢出一般有两个原因 xff1a 1 此任务函数的代码量太大 或调用了某个比较大的函数 2 此任务的函数内有比较大的局部变量的数组 调试方法 xff1a 1 先关闭所有任务再逐个打开 xff0c
  • 安装在win10环境下的Jenkins添加本地虚拟机centos7作为从机遇到的问题,报错:SSH Connection failed with IOException: "Key exchange

    首先声明我的Jenkins版本是 xff1a 2 31版 因为不同版本页面有所不一样 安装在win10环境下的Jenkins添加本地虚拟机centos7作为从机遇到的问题 xff0c 报错情况如下 xff1a Searching for 1
  • Linux du命令和df命令区别

    1 xff0c 两者区别 du xff0c disk usage 是通过搜索文件来计算每个文件的大小然后累加 xff0c du能看到的文件只是一些当前存在的 xff0c 没有被删除的 他计算的大小就是当前他认为存在的所有文件大小的累加和 d
  • ML大杂烩:**常见机器学习算法公式梳理

    机器学习方法有一个进阶的过程 xff0c 不同的方法族 xff0c 都有其基础和逐渐进化的模型 每一个更新的模型一般是对上一个简单模型的改进 xff0c 比如SVM就直接改进了近邻方法 xff0c 降低了保留的实例个数 本文有大量修改 xf
  • libuv笔记 (一)Threads

    Threads 线程在现代程序开发中会很常见 xff0c 当然Libuv也不能缺席这一块 xff0c 记得你在使用过程中要非常认真的处理 各种原始的同步问题 线程会在内部使用 xff0c 用来在执行系统调用时伪造异步的假象 libuv通过线
  • SLAM: SLAM基本流程—VSLAM扫盲之旅

    在很多机器人的论文和书籍里面 xff0c 劈头第一页即是 xff0c 经典的SLAM视觉框架是过去十几年前已经成熟的研究结果 xff0c 这个框架和算法本身已经没有太多理论可以操作的空间 封杀了很多人的SLAM科研之路 xff0c 把SLA
  • 三维重建:SLAM的尺度和方法论问题

    百度百科的定义 此文引用了其他博客的一些图像 xff0c 如有侵权 xff0c 邮件联系删除 作为算法的SLAM xff0c 被称为同步相机位姿确定和地图构建 作为一个工程的SLAM xff0c 有众多的算法 在计算机视觉中 三维重建是指根
  • 相机标定:PNP基于单应面解决多点透视问题

    利用二维视野内的图像 xff0c 求出三维图像在场景中的位姿 xff0c 这是一个三维透视投影的反向求解问题 常用方法是PNP方法 xff0c 需要已知三维点集的原始模型 本文做了大量修改 xff0c 如有不适 xff0c 请移步原文 xf

随机推荐