news 2026/6/10 20:36:53

c++类和对象(上)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
c++类和对象(上)

类是c++的独特形式,可以在类中包括函数进行。

对象是通过类创建的一个个变量。

类的存储

类中的每一个

类中的函数,不存入类的内存。如图定义了一个类,有一个int类型,4字节。一个函数无内存。

类的存储的大小还要看对齐数

对齐数=(对齐数默认的数)和(类内的成员变量的大小)的较小值,每一个类成员都有一个对齐数。

内存大小为(成员变量的对齐数最大值)的整数倍

vs(对齐数)默认是8

如果是类嵌套,取嵌套中的最大对齐数。

原因1:平台问题,有些硬件平台只能取特定类型的数据。cpu不能从任意位置开始读只能从整数倍开始,不能读任意字节只能读固定字节。如下图4的整数倍开始读,一次性读取4字节。

2:性能原因,处理器处理未对齐的需要两次,对齐的只需要1次。

如果定义的类没有内容,内存为1字节证明存在。成员变量没有内容也会给1字节证明有这个成员。

c++,定义了一个this指针作为。隐藏在类中的函数的一个参数,指向自身,不可修改。

#include<iostream> #include<string> using namespace std; class jst{ public: int a; //void print(jst* const this) void print( ){ cout<<a<<endl; } }; class st1{ }; class st2{ st1 a; st1 b; }; int main(){ jst s; s.a=10; s.print(); //s.print(&s); cout<<sizeof(st1)<<endl; cout<<sizeof(st2)<<endl; return 0; }

类中直接访问用.,通过指针访问用->。

不能自己显示的写this指针。

可以在函数体内可以用。

this指针存储到栈中。

#include<iostream> #include<string> using namespace std; class jst{ public: void print(){ cout<<"666"<<endl; } }; int main(){ jst* s=nullptr; s->print(); return 0; }

可以正常运行,因为函数没有存在类中,调用后只传了s的地址。

在c++的类中,可以把不同的数据封装到不同的区,防止胡乱调用。如下面的代码,只能通过jst中的函数进行操作。实现不能直接操作s.a,必须间接操作。

#include<iostream> #include<string> using namespace std; class jst{ public: void push(int n,int m){ a[n]=m; } void print(int n){ cout<<a[n]; } private: int a[4]; }; int main(){ jst s; s.push(0,1); s.print(0); return 0; }

默认成员函数

在类中如果你没有创建,编译器自动生成的函数,还有两个移动构造,移动赋值。

初始化和清理。构造函数初始化工作。

析构函数清理工作。

拷贝复制, 拷贝构造是使用同类对象初始化创建对象。

赋值重载,把一个对象赋值给另一个对象。

取地址重载 普通对象和const对象的取址

构造函数

函数名和类名相同。

无返回值。不需要写void。

对象创建时自动调用。

构造函数可以重载。

无参

#include<iostream> #include<string> using namespace std; class jst{ public: jst(){ a[0]=1; a[1]=2; a[2]=3; a[3]=4; } void print(){ cout<<a[0]<<" "<<a[1]<<" "<<a[2]<<" "<<a[3]; } private: int a[4]; }; int main(){ jst s; s.print(); return 0; }

带参,在创建时跟在创建末尾。

#include<iostream> #include<string> using namespace std; class jst{ public: jst(int q,int w,int e,int r){ a[0]=q; a[1]=w; a[2]=e; a[3]=r; } void print(){ cout<<a[0]<<" "<<a[1]<<" "<<a[2]<<" "<<a[3]; } private: int a[4]; }; int main(){ jst s(2,3,4,5); s.print(); return 0; }

全缺省。可以自己初始。

#include<iostream> #include<string> using namespace std; class jst{ public: jst(int q=1,int w=2,int e=3,int r=4){ a[0]=q; a[1]=w; a[2]=e; a[3]=r; } void print(){ cout<<a[0]<<" "<<a[1]<<" "<<a[2]<<" "<<a[3]; } private: int a[4]; }; int main(){ jst s(0,0); s.print(); return 0; }

默认构造是不用传参的就是默认构造,包括无参和全缺省。

默认生成2个中的一个.

3个构造函数只能存在一个。

看编译器生成无参函数和全缺省函数。

对于自定义的类型会调用自定义的构造函数。

#include<iostream> #include<string> using namespace std; class jst{ public: jst(){ a[0]=1;a[1]=2;a[2]=3;a[3]=4; } void print(){ cout<<a[0]<<" "<<a[1]<<" "<<a[2]<<" "<<a[3]<<endl; } private: int a[4]; }; class jst2{ public: void print(){ a1.print(); a2.print(); } private: jst a1; jst a2; }; int main(){ jst2 s; s.print(); return 0; }

一般构造函数自己写。

析构函数

析构函数名是在类名前加上字符~;

无参无返回值。

一个类只有一个析构。

对象结束会自动调用。

如果不写会自动生成。

对于自定义,也会调用它的析构。

#include<iostream> #include<string> #include<cstdlib> using namespace std; class jst{ public: jst(){ a=(int*)malloc(sizeof(int)*4); a[0]=1;a[1]=2;a[2]=3;a[3]=4; } ~jst(){ cout<<"0"<<endl; free(a); } void print(){ cout<<a[0]<<" "<<a[1]<<" "<<a[2]<<" "<<a[3]<<endl; } private: int* a; }; class jst1{ public: jst1(){ a=(int*)malloc(sizeof(int)*4); a[0]=1;a[1]=2;a[2]=3;a[3]=4; } ~jst1(){ cout<<"1"<<endl; free(a); } void print(){ cout<<a[0]<<" "<<a[1]<<" "<<a[2]<<" "<<a[3]<<endl; } private: int* a; }; class jst2{ public: void print(){ a1.print(); a2.print(); } private: jst a1; jst1 a2; }; int main(){ jst2 s; s.print(); return 0; }

后定义的先析构。

对于自定义函数总会使用自定义的析构。

没有申请资源的类可以不写析构。

显示写析构,也会自动调用默认析构。

运算符重载

运算符在类中可以重载。

#include<iostream> #include<string> #include<cstdlib> using namespace std; class Data{ public: Data(int year=1,int yue=1,int day=1 ){ _year=year; _yue=yue; _day=day; } int que(int n){ if(n>0&&n<4){ if(n==1) return _year; else if(n==2) return _yue; else return _day; } } private: int _year;int _yue;int _day; }; bool operator==(Data d1,Data d2){ return d1.que(1)==d2.que(1)&&\ d1.que(2)==d2.que(2)&&\ d1.que(3)==d2.que(3); }; int main(){ Data t1(2,2,2); Data t2; Data t3; if(t1==t2) cout<<"666"<<endl; else cout<<"999"<<endl; if(t3==t2) cout<<"666"<<endl; return 0; } 或者 class Data{ public: Data(int year=1,int yue=1,int day=1 ){ _year=year; _yue=yue; _day=day; } int que(int n){ if(n>0&&n<4){ if(n==1) return _year; else if(n==2) return _yue; else return _day; } } bool operator==(Data d2){ return _year==d2._year&&\ _yue==d2._yue&&\ _day==d2._day; }; private: int _year;int _yue;int _day; };

第二种方式使用的this指针,t1.opertaor==(t2),可以省略为t1==t2。

只能对于已有的操作符重载,不能重新创建一个全新的操作符。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 14:20:10

窗口相关操作的总结

本文重点 在前面的课程中,我们学习了Flink中关于窗口的一系列操作,本文对前面的内容进行总结 总结内容 窗口类型 从窗口的驱动类型角度看,窗口可以分为时间窗口和计数窗口 从窗口的按照分配数据的规则来看,窗口可以分为滚动窗口和滑动窗口和会话窗口和全局窗口 将二者结…

作者头像 李华
网站建设 2026/6/9 23:35:58

5个步骤快速掌握hekate引导程序的完整使用指南

hekate作为任天堂Switch平台上最强大的图形化引导加载器&#xff0c;为设备带来了前所未有的自定义能力。这款基于GUI的引导程序能够替代官方启动流程&#xff0c;让用户轻松管理多系统环境、备份重要数据&#xff0c;以及运行各种自制软件。 【免费下载链接】hekate hekate - …

作者头像 李华
网站建设 2026/6/10 11:03:39

12306反反爬虫策略:Python网络请求优化实战

一、引言&#xff1a;12306反爬虫的严峻挑战 12306作为中国铁路售票系统&#xff0c;每天面临着海量的抢票请求&#xff0c;其反爬虫机制异常严格&#xff1a;IP封锁、验证码、请求频率限制、会话追踪等。要在这样的环境下实现稳定抢票&#xff0c;必须设计一套完善的反反爬虫策…

作者头像 李华
网站建设 2026/6/10 13:15:16

网络编程入门:从IP到TCP全解析

一、引言昨天讲了闭包与装饰器,今天给大家讲一下网络编程.二、计算机网络概述1.网络的概念网络就是将具有独立功能的多台计算机通过通信线路和通信设备连接起来&#xff0c;在网络管理软件及网络通信协议下&#xff0c;实现资源共享和信息传递的虚拟平台。2.为什么要学网络学习…

作者头像 李华
网站建设 2026/6/10 11:05:26

基于Java的安全生产投诉智慧管理系统的设计与实现全方位解析:附毕设论文+源代码

1. 为什么这个毕设项目值得你 pick ?安全生产投诉智慧管理系统结合了会员管理、投诉处理等17个模块&#xff0c;旨在提升企业安全管理效率。与传统选题相比&#xff0c;本系统功能更全面、创新性强且实用性高。不仅涵盖传统的事故管理、培训管理和设备维护记录管理&#xff0c…

作者头像 李华
网站建设 2026/6/10 0:53:36

LangChain RAG-递归文档树检索实施高级RAG优化理解

01. RAPTOR 递归文档树策略 在传统的 RAG 中&#xff0c;我们通常依靠检索短的连续文本块来进行检索。但是&#xff0c;当我们处理的是长上下文时&#xff0c;我们就不能仅仅将文档分块嵌入到其中&#xff0c;或者仅仅使用上下文填充所有文档。相反&#xff0c;我们希望为 LLM…

作者头像 李华