类描述看上去很像包含成员函数以及public和private可见性标签的结构声明,实际上,C++对结构进行了扩展,使之具有与类相同的特性。它们之间的唯一区别是:结构的默认访问类型是public而类的默认访问类型为private。在C++中通常使用类来实现类描述,而把结构限制为只表示纯粹的数据对象(常被称为普通老数据POD(Plain Old Data)结构,)。

C和C++中结构体的不同:

  • C语言中的结构体不能为空,否则会报错
  • C语言中的结构体只涉及到数据结构,而不涉及到算法,也就是说在C中数据结构和算法是分离的。换句话说就是C语言中的结构体只能定义成员变量,但是不能定义成员函数。
  • 在C++中既可以定义成员变量又可以定义成员函数, C++中的结构体和类体现了数据结构和算法的结合。
  • 虽然C语言的结构体中不能定义成员函数,但是却可以定义函数指针,不过函数指针本质上不是函数而是指针,所以总的来说C语言中的结构体只是一个复杂数据类型 ,只能定义成员变量,不能定义成员函数,不能用于面向对象编程。
  • 在 C 中,必须显式使用 struct 关键字来声明结构。 在 c + + 中,不需要在 struct 定义类型后使用关键字。

C++中类和结构

  • 结构是实值类型(Value Types),而类则是引用类型(Reference Types)。
  • 结构使用栈存储(Stack Allocation),而类使用堆存储(Heap Allocation)。

概念:class和struct的语法基本相同,从声明到使用,都很相似,但是struct的约束要比class多,理论上,struct能做到的class都能做到,但class能做到的stuct却不一定做的到。
类型:struct是值类型,class是引用类型,因此它们具有所有值类型和引用类型之间的差异。
效率:由于栈的执行效率要比堆的执行效率高,但是栈资源却很有限,不适合处理逻辑复杂的大对象,因此struct常用来处理作为基类型对待的小对象,而class来处理某个商业逻辑。
总结:
(1) 在表示诸如点、矩形等主要用来存储数据的轻量级对象时,首选struct。

(2) 在表示数据量大、逻辑复杂的大对象时,首选class。

(3) 在表现抽象和多级别的对象层次时,class是最佳选择

如果用C语言实现一个类似面向对象的类

// 写法一
#include <stdio.h>
typedef struct Actress {int height; // 身高int weight; // 体重int age;    // 年龄(注意,这不是数据库,不必一定存储生日)void (*desc)(struct Actress*);
} Actress;void profile(Actress* obj) {printf("height:%d weight:%d age:%d\n", obj->height, obj->weight, obj->age);
}int main() {Actress a;a.height = 168;a.weight = 50;a.age = 20;a.desc = profile;a.desc(&a);return 0;
}

想达到面向对象中数据和操作封装到一起的效果,只能给struct里面添加函数指针,然后给函数指针赋值。在C语言的项目中你很少会看到这种写法,主要原因就是函数指针是有空间成本的。一般会按照如下的方法写:

// 写法二
#include <stdio.h>
typedef struct Actress {int height; // 身高int weight; // 体重int age;    // 年龄(注意,这不是数据库,不必一定存储生日)} Actress;void desc(Actress* obj) {printf("height:%d weight:%d age:%d\n", obj->height, obj->weight, obj->age);
}int main() {Actress a;a.height = 168;a.weight = 50;a.age = 20;desc(&a);return 0;
}:

再看一个普通的C++类:

// 写法二
#include <stdio.h>
class Actress {public:int height; // 身高int weight; // 体重int age;    // 年龄(注意,这不是数据库,不必一定存储生日)void desc() {printf("height:%d weight:%d age:%d\n", height, weight, age);}};int main() {Actress a;a.height = 168;a.weight = 50;a.age = 20;a.desc();return 0;
}

看着像写法一?其实相当于写法二。C++编译器实际会帮你生成一个类似C语言写法二的形式(这也算是C++ zero overhead指导方针的一个体现)。看到这里就明白了:C++中类和操作的封装只是对于程序员而言的。而编译器编译之后其实还是面向过程的代码。编译器帮你给成员函数增加一个额外的类指针参数,运行期间传入对象实际的指针。类的数据(成员变量)和操作(成员函数)其实还是分离的。
每个函数都有地址(指针),不管是全局函数还是成员函数在编译之后几乎类似。

C++结构体和类总结

  • 结构体和类最大的区别就是前者访问控制默认为public,而类的默认访问控制是private。而对于public,private,protected的访问控制都是在编译期间由编译器检查的,编译通过后,程序执行过程中就不存在什么访问限制了。笼统一点讲,它们在底层只是类型名称不同,原理都相同。
  • 类与对象,类是一个抽象的概念,而对象则是这个抽象概念里的一个具体实例。(如人–CXX…)类一般由数据成员函数成员组成,而具体对象大小的计算只看数据成员,函数成员属于执行代码,不属于类对象的数据。除本身外,类中的数据成员可以是任何已知的数据类型。
  • 为什么类中不能定义自身的对象呢?因为类在实例化时,必须要知道它的大小,而如果有自身,会形成递归定义,没有出口。但注意自身的指针类型是可以的,因为任何类型的指针大小是已知的。
  • 类对象大小一般就是数据成员大小之和,但也有些特殊情况不符合这个公式。(1)空类,至少占1字节大小,而不是不占内存空间,如果不占内存大小,那么空类就无法实例化。但是空类就算没有数据成员,也可以有函数成员的,所以仍然需要实例化,而这个至少会分配1字节空间给空类,就是用于实例化的。(2)字节对齐 (3)静态成员数据,类似局部静态数据,存在域全局,作用域局部,在编译期间就已经初始化,保存在全局数据区中。它的大小不算在类对象里。
  • this指针:使用过程中被编译器给隐藏起来了,它其实就是个指针,保存调用对象的首地址,指向当前调用者对象本身。对象的成员函数形参处隐式的有这个this,其实是在调用成员函数时,编译器做了一个小动作:利用寄存器ecx保存了对象的首地址(this),并以寄存器传参的方式传递到成员函数中。这也是在成员函数中能直接访问成员数据的原因(this->data),也是判断一个函数不是一般函数而是成员函数的依据。
  • 对象作为函数参数:这个不像数组做参数只传递首地址,而是将对象的所有数据成员拷贝一份全部传递过去。这个过程其实会调用系统的拷贝构造函数,就是简单的赋值过程(如果自己写了这个函数,会替换系统的),所以对于有动态内存分配的类,使用这种传参,调用系统的拷贝构造函数,会出现一个这样的错误,这种传参其实是实参与形参处的两个对象保存着相同的数据,而形参处对象在函数调用结束就会释放调用对应的析构函数,所以对于实参和参数处的两个对象都指向的动态空间被释放了。这时实参处对象的指针还在,但所指内存已经释放了。所以对于这种需要我们自己定义拷贝构造函数,一般有两种思路:(1)深拷贝数据,即对于指针数据不仅拷贝指针本身而且指针所指数据也同时拷贝(2)设置引用计数。但是对于对象传参我们一般使用指针或引用形式,这样即可以避免上面所说错误,同时效率也更高。
  • 对象作为返回值:情况和对象作为函数参数一样。

C++中类(class)和结构(struct)的区别相关推荐

  1. C#中类与结构体的区别

    1.在C#中结构体类型定义时,成员是不能初始化的,这样就导致了,定义结构体变量时,变量的所有成员都要自己赋值初始化.但对于类,在定义类时,就可以初始化其中的成员变量,所以在定义对象时,对象本身就已经有 ...

  2. C和C++结构体的区别

    C和C++结构体的区别 转自:https://www.cnblogs.com/qiumingcheng/p/7814970.html 1.C的结构体内不允许有函数存在,C++允许有内部成员函数,且允许 ...

  3. typedefnbsp;struct与struct的区别

    typedef struct与struct的区别 1. 基本解释 typedef为C语言的关键字,作用是为一种数据类型定义一个新名字.这里的数据类型包括内部数据类型(int,char等)和自定义的数据 ...

  4. struct和typedef struct的区别(转)

    转载来源:https://www.cnblogs.com/qyaizs/articles/2039101.html 分三块来讲述: 1 首先://注意在C和C++里不同 在C中定义一个结构体类型要用t ...

  5. NET中class与struct的区别简析

    在没有class的面向过程的编程时代,struct是封装数据的利器,没它不行.但自从面向对象编程以来,class横空出世,大家高呼着"万事万物皆对象",把class含在嘴里,握在手 ...

  6. c++中类模板与结构体模板总结

    c++中类模板与结构体模板总结 Child_heart 2018-04-09 22:05:23  6728  已收藏 9 分类专栏: C++ 版权 今天刚刚编完数据结构中的单链表,其中用到了类模板,发 ...

  7. struct和typedef struct的区别

    在了解struct和typedef struct之前,我们先学习下typedef的定义和用法. typedef为C语言的关键字,作用是为一种数据类型定义一个新名字.这里的数据类型包括内部数据类型(in ...

  8. struct与typedef struct的区别

    typedef是类型定义的意思.typedef struct 是为了使用这个结构体方便. 具体区别在于: 若struct node {}这样来定义结构体的话.在申请node 的变量时,需要这样写,st ...

  9. struct 和 typedef struct 的区别

    文章目录 前言 struct和typedef struct的区别 C语言中的struct和typedef struct struct typedef struct C++中的struct和typede ...

  10. C#类与结构体的区别

    C#中类(class)与结构体(stract)的区别: 1.类是引用类型,结构体是值类型: 2.结构体不支持继承,但可以实现接口,类即支持继承也能实现接口: 3.结构体中不可以声明无参的构造函数: 4 ...

最新文章

  1. .net里鼠标选中的text数据怎么获取_怎么利用Excel设置当天生日提醒功能
  2. Java 集合系列10: HashMap深入解析(2)
  3. *.zip、*.tar、*.tar.gz、*.tar.bz2、*.tar.xz、*.jar、*.7z
  4. mysql异步查询 java_基于 mysql 异步驱动的非阻塞 Mybatis
  5. 最大子序和--动态规划
  6. 用Python显示灰度图像的灰度直方图
  7. Java对证书的操作
  8. 解构给默认值_使用 JavaScript 解构让代码更优雅
  9. 计算机操作系统考试习题
  10. web 开发生产率_11种可帮助Web开发人员克服最后期限的生产力工具
  11. Mybatis之插件
  12. html 英文发音,一些英文字母的发音
  13. php调用海康,手把手教你php对接海康api
  14. 解决excel里面“取消隐藏”是灰色的问题
  15. html引入微软雅黑,求让所有浏览器支持微软雅黑的方法_html/css_WEB-ITnose
  16. 数据库报duplicate XXX entry for key primary错误的可能原因以及解决方法
  17. Origin画图技巧之3D锥形图
  18. vue 添加子路由 默认选中子路由
  19. Apache的性能解读
  20. gcc利用-m32编译报错问题处理

热门文章

  1. C#中public 、private、protect的区别
  2. 如何微信多开,Mac电脑 同时登陆一个或多个微信、QQ
  3. Txilm Protocol: Monoxide公链系统中的区块压缩算法
  4. 天高任鸟飞,在你还苦闷Android出路时,总有人在系统钻研为高级开发做准备
  5. Tarena - 表的创建
  6. 用让新海诚本人惊讶的 AI 模型制作属于你的动漫视频
  7. current root password的解决方案
  8. 第12集 关于库卡机器人对需要减速和插值方式说明
  9. WSL2跟踪 - 18945: 通过localhost直接访问 WSL2 容器中的服务
  10. R语言 编写自定义函数