C++初阶语法——类和对象
前言:C语言中的结构体,在C++有着更高位替代者——类。而类的实例化叫做对象。
本篇文章不定期更新扩展后续内容。
目录
- 一.面向过程和面向对象初步认识
- 二.类
- 1.C++中的结构体
- 2.类的定义
- 类的两种定义方式
- 3.类的访问限定符及封装
- 访问限定符说明
- 4.类的实例化
- 对象只存储成员变量,不存储成员函数
- 成员函数存储在公共代码区
- 5.this指针
- 三.六大默认成员函数
- 1.构造函数
- 构造函数特点(重点)
- 默认构造函数(重点)
- 初始化列表
- 2.析构函数
- 析构函数特点
一.面向过程和面向对象初步认识
在学习C语言的时候,我就时常听说过面向过程和面向对象,但是对这两个概念的认知非常模糊,那么这两者有什么区别呢?
C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。
而C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。我们不需要关注过程是怎么完成的,我们只需要关注对象间的交互。
面向对象有3大特性——封装,继承,多态。
二.类
1.C++中的结构体
C语言中结构体中只能定义变量,而在C++中,结构体中不仅能定义变量,还可以定义函数(struct升级成了类)。
以数据结构——栈为例:
直接在结构体内定义函数。
实例化对象时,无需再写struct,只需写结构体名。
#include<iostream>
using namespace std;
typedef struct Stack {int* a;int capacity;int top;void Init() //定义函数{a = nullptr;capacity = 0;top = 0;}
}ST;
int main()
{Stack s1; // 无structs1.Init();return 0;
}
2.类的定义
在C++中,类更喜欢用class而非struct。
这两者在默认访问限定上有些区别,struct默认为public,而class默认为private,更符合面向对象的要求。这也是为什么更喜欢使用class。该点在下文默认访问限定符也会讲解。
class Classname
{//类体:成员函数+成员变量}; //跟结构体一样有分号不要忘
class为定义类的关键字,Classname为类名,{}中为类的主体,类体中的内容称为类的成员,类中的变量称为类的属性或成员变量,类中的函数称为类的方法或成员函数。
类的两种定义方式
一种就是向上面的栈一样将函数声明定义都写在类里面,值得一提的是,这种函数会被编译器当成内联函数。
还有一种就是将类声明放在头文件中,在源文件中定义函数,但是需要注意的是,成员函数名前需要加类名::(域作用限定符),一般第二种用的更多。
//obj.h
#include<iostream>
using namespace std;typedef struct Stack {int* a;int capacity;int top;void Init();
}ST;//test.cpp
#include"obj.h"
void Stack::Init() // 类名::
{a = nullptr;capacity = top = 0;
}
3.类的访问限定符及封装
C++实现封装的方式:用类将对象的属性(成员变量)和方法(成员函数)结合在一起,让对象更加完善,通过访问限定符选择性的将其接口提供给外部的用户使用。
共有3种访问限定符:在诸如php,java等语言中都有。
访问限定符说明
利用好访问限定符,可以有效保护好类中的数据,防止其他人随便访问。
1.public:公有的类成员可以在任何地方被访问。
protect:受保护的类成员则可以被其自身以及其子类和父类访问。
private:私有的类成员则只能被其定义所在的类访问。
(在学继承之前,protect和private使用起来没差)
2.struct默认为public,class默认为private。
3.访问权限作用域从该访问限定符开始到下一个访问限定符出现。
4.如果后面没有访问限定符,作用域到 } 为止。
5.一般情况下,成员变量都设置为private。
以日期类为例:
class Date {
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}
private:int _year; //声明,没有定义,不占空间int _month;int _day;
};
4.类的实例化
用类创建对象的过程,叫做类的实例化。
1.类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来存储它。
2.一个类可以实例化出多个对象。实例化出的对象才占用实际的内存空间,且只存储成员变量,不存储成员函数。
以日期类为例:
class Date {
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}
private:int _year; //声明,没有定义,不占空间int _month;int _day;
};int main()
{Date d1; // 类的实例化Date d2, d3; // 一个类可以实例化出多个对象//下面两行代码可行吗,为什么?//Date::_year = 1; //并没有实例化对象,只是声明没有开空间,更不必说初始化了。//d1._year = 1; //实例化了呢?也不行,因为_year是私有成员变量,只能在Date类中更改。return 0;
}
对象只存储成员变量,不存储成员函数
上文说过,类的主体有两个:成员变量和成员函数。
但实际上实例化的对象中只存储成员变量,而成员函数存储在公共代码区。
请看下例代码(类的空间大小计算和结构体一样,遵循结构体内存对齐规则):
class Date {
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}
private:int _year; //声明,没有定义,不占空间int _month;int _day;
};int main()
{Date s1;cout << sizeof(Date) << endl;cout << sizeof(s1) << endl;return 0;
}
控制台输出如下:
可以发现,12是只计算成员变量得到的结果,因此可以得知对象中并不存储成员函数。
之所以这样是因为成员函数对每个对象都是一样的,其会被存储在公共代码区,这样不必要在每次实例化对象时都存储一次成员函数,大大提高了程序效率。
成员函数存储在公共代码区
请看如下代码,各位觉得能够运行成功吗?
class Example
{
public:void Print(){cout << "Print()" << endl;}
private:int _a;int _b;
};
int main()
{Example* s1 = nullptr;s1->Print(); //空指针指向????return 0;
}
控制台显示如下:
运行成功了,为什么呢?上面不是空指针解引用问题吗,程序应该崩溃呀?
答:上面说过成员函数存储在公共代码区,直接向公共代码区call该函数的地址,不需要向对象s1中找东西,因此不会发生空指针解引用操作。
5.this指针
类的成员函数中都隐藏了一个this指针参数。
this在实参和形参位置不能显示写,但是可以在类里面显示的用。
this指针不可被更改.
this指针可以为空(就是上面成员函数存在公共代码区的例子)。
this指针存在栈帧里面。(不要误以为this存在对象中,this就是一个形参,跟普通形参一样存在栈帧里面)。
仍以日期类为例:
class Date {
public://this在实参和形参中不能显示地写//在类中可以显示地用(没什么价值)void Init(int year, int month, int day){_year = year;_month = month;_day = day;}/*void Init(Date* const this ,int year, int month, int day){this->_year = year;this->_month = month;this->_day = day;}*/
private:int _year;int _month;int _day;
};int main()
{Date d1;d1.Init(2023, 8, 11); //d1.Init(&d1,2023,8,11);return 0;
}
三.六大默认成员函数
C++中有六个默认成员函数,我们不写的话,它们会自动生成。

1.构造函数
构造函数最便捷的地方就是自动调用,可以在我们忘了初始化的时候发挥作用。
构造函数是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造,但是构造函数的主要任务并不是开空间创建对象,而是初始化对象。
其特征如下:
1.函数名和类名相同。
2.无返回值(不需要写void)。
3.对象实例化时编译器自动调用对应的构造函数。
4.构造函数可以重载。(可以写多个构造函数,提供多种初始化方式)
class Date {
public://构造函数,函数名和类名相同。Date(int year = 1, int month = 1, int day = 1) //全缺省参数{cout << "Date()" << endl; // 借此观察构造函数是否被调用_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;
};int main()
{Date d1(2023,8,11); // 对象实例化时自动调用构造函数,一定记住!!! 实参可以任意更改//在对象d1后面接实参是构造函数的特殊的初始化规则。 //Date d2(); //不可以在对象后加括号而不给实参,因为编译器分不清你是在创建对象还是调用函数。return 0;
}
控制台输出如下:可以看到,我们并没有调用Date函数,Date函数在对象实例化时自动调用了。
构造函数特点(重点)
构造函数,是默认成员函数之一,我们不写,编译器也会自动生成。
编译生成的默认构造函数的特点:
1.我们写了就不会自动生成了,我们不写编译器会自动生成一个无参的默认构造函数。
2.内置类型不会处理(C++11,支持声明时给缺省值,但是有了缺省值就会处理)
3.自定义类型的成员才会处理,会去调用这个成员的默认构造函数。(注意是默认构造函数,而非是构造函数)(内置类型就是诸如int,double这种语言提供的类型,而自定义类型就是我们自己定义的类型,比如上文的Date。
需要注意的是:int* 是内置类型,Date* 也是内置类型。只要是指针就是内置类型)
默认构造函数(重点)
ps:这个地方刚开始学的时候理解起来挺难的,我被绕的晕头转向的。还是要多学多看代码啊。
无参的构造函数和全缺省的构造函数(此两者都是我们自己写的)都被称为默认构造函数,并且默认构造函数只能有一个。
共有3种默认构造函数:
1.无参的构造函数
2.全缺省的构造函数
3.我们没写编译器自动生成的构造函数。
总结:这3种默认构造函数有一个共同点,就是不传参就可以调用。
多个默认构造函数同时存在会有歧义。
如下图所示,编译器就会显示无默认构造函数。
而将Date写成全缺省就可以正常运行(对应上文的全缺省的构造函数是默认构造函数)
初始化列表
2.析构函数
析构函数:与构造函数的作用相反,析构函数不是完成对对象本身的销毁,局部对象的销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作(malloc,realloc出来的空间等)。
析构函数的特性:
1.析构函数名是在类名前加上字符~
2.无参数无返回值
3.一个类只能有一个析构函数。若未显示定义(我们没写),系统会自动生成默认的析构函数。注意:析构函数不能重载。
4.对象声明周期结束时,C++编译系统自动给调用析构函数。
5.后定义的对象先析构(栈帧)。
析构函数特点
跟构造函数类似,析构函数具有以下特点:
1.我们写了就不会自动生成了,我们不写编译器会自动生成一个析构函数。
2.内置类型成员不会处理。
3.自定义类型成员会调用这个成员的析构函数。
·总结:一般情况下都需要我们自己写构造函数,决定初始化方式。而成员变量全是自定义类型时,可以考虑不写构造函数。
文末BB:对哪里有问题的朋友,尽管在评论区留言,若哪里写的有问题,也欢迎朋友们在评论区指出,博主看到后会第一时间确定修改。最后,制作不易,如果对朋友们有帮助的话,希望能给博主点点赞和关注.

相关文章:
C++初阶语法——类和对象
前言:C语言中的结构体,在C有着更高位替代者——类。而类的实例化叫做对象。 本篇文章不定期更新扩展后续内容。 目录 一.面向过程和面向对象初步认识二.类1.C中的结构体2.类的定义类的两种定义方式 3.类的访问限定符及封装访问限定符说明 4.类的实例化对…...
linux学习(进程创建)[8]
创建进程 myproc.c #include <stdio.h> #include <unistd.h>int main() {printf("我是父进程\n");pid_t id fork();if(id < 0){printf("创建子进程失败\n");return 1;}else if(id 0){while(1){printf("我是子进程: pid…...
Linux基础与应用开发系列九:各类系统函数
open_close函数 OPEN函数 头文件: #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> 函数原型: 当文件存在时 int open(const char* pathname,int flags) 当文件不存在时 int open (const char* pathname,int f…...
国产数据库排行
目录 一、理论 1.国产数据库排行 2.数据 一、理论 1.国产数据库排行 (1)墨天轮榜单 墨天轮国产数据库流行度排行于2019年6月推出,通过近50个维度的数据来考察近300个国产数据库的流行度排行,每月1日更新排行数据,…...
数学符号说明——三角等号(≜)
三角等号 ,LaTex语法宏 (\triangleq),Unicode(U225C),又称 "delta equal to(Δ 等)"。可以读作 "等于"、"根据定义 x 等于 y "。 有时候,用在数学(和物理学)的某种定义中。例如&#…...
健启星|医学营养的市场先行者
随着《“健康中国2030”规划纲要》、《国民营养计划(2017-2030年)》等政策的陆续发布,标志着以传统药物治疗为中心的医疗模式时代正式转型到以预防和康复为中心的新的医学营养时代。在此背景下,符合时代需求的特医食品成为“医学营…...
从 GPT4All 体验 LLM
推荐:使用 NSDT场景编辑器 助你快速搭建可编辑的3D应用场景 什么是 GPT4All? 术语“GPT”源自 Radford 等人 2018 年论文的标题“通过生成预训练提高语言理解”。本文描述了如何证明变压器模型能够理解人类语言。 从那时起,许多人尝试使用转…...
QGraphicsView实现简易地图4『局部加载-地图漫游』
前文链接:QGraphicsView实现简易地图3『局部加载-地图缩放』 当鼠标拖动地图移动时,需要实时增补和删减瓦片地图,大致思路是计算地图从各方向移动时进出视口的瓦片坐标值,根据变化后的瓦片坐标值来增减地图瓦片,以下将…...
ubuntu 安装 nvidia 驱动
ubuntu 安装 nvidia 驱动 初环境与设备查询型号查询对应的驱动版本安装驱动验证驱动安装结果 本篇文章将介绍ubuntu 安装 nvidia 驱动 初 希望能写一些简单的教程和案例分享给需要的人 环境与设备 系统:ubuntu 设备:Nvidia GeForce RTX 4090 查询型…...
探索APP界面布局的艺术与技巧:从入门到精通
引言 在当今数字化时代,移动应用程序(APP)成为人们生活中不可或缺的一部分。而一个成功的APP界面布局是吸引用户、提升用户体验的关键因素之一。本文将带您深入探索APP界面布局的艺术与技巧,从入门到精通,让您能够轻松…...
回归预测 | MATLAB实现POA-CNN-GRU鹈鹕算法优化卷积门控循环单元多输入单输出回归预测
回归预测 | MATLAB实现POA-CNN-GRU鹈鹕算法优化卷积门控循环单元多输入单输出回归预测 目录 回归预测 | MATLAB实现POA-CNN-GRU鹈鹕算法优化卷积门控循环单元多输入单输出回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 MATLAB实现POA-CNN-GRU鹈鹕算法优化卷积门…...
15.3.2 【Linux】系统的配置文件:/etc/crontab,/etc/cron.d/*
这个“ crontab -e ”是针对使用者的 cron 来设计的,如果是“系统的例行性任务”时, 该怎么办呢?是否还是需要以 crontab -e 来管理你的例行性工作调度呢?当然不需要,你只要编辑/etc/crontab 这个文件就可以。有一点需…...
新版PMP考试中,敏捷是怎么考的?
01新版考试中的敏捷是怎么考的? 接下来说一下大家最为关注的敏捷内容。这次改版后,题目中添加了大量的敏捷题型,总体比重还是很高的,主观感觉达到了1/3。但和ACP认证相比,PMP中对敏捷管理技术的考察相对来说比较简单&…...
uniapp-----封装接口
系列文章目录 uniapp-----封装接口 uniapp-----分包 文章目录 系列文章目录 uniapp-----封装接口 uniapp-----分包 文章目录 前言 一、技术 二、封装步骤 1.准备 编辑 2.代码填充 request.js: api.js: min.js 页面使用 总结 前言 uniapp的主包要求大…...
[oeasy]python0081_[趣味拓展]ESC键进化历史_键盘演化过程_ANSI_控制序列_转义序列_CSI
光标位置 回忆上次内容 上次了解了 新的转义模式 \033 逃逸控制字符 escape 这个字符 让字符串 退出标准输出流进行控制信息的设置 可以设置 光标输出的位置 ASR33中的ALT MODE 是 今天的ESC键吗????🤔 查询文档…...
第十六次CCF计算机软件能力认证
第一题:小中大 在数据分析中,最小值最大值以及中位数是常用的统计信息。 老师给了你 n 个整数组成的测量数据,保证有序(可能为升序或降序),可能存在重复的数据。 请统计出这组测量数据中的最大值、中位数以及最小值&am…...
关于Postman如何配置随请求携带token
文章目录 一些吐槽实际应用 一些吐槽 首先吐槽一下 postman官网的文档说明,真是乱七八糟,一点都不清晰,能不能好好写用户手册啊(比如把用户都当作初始小白) 然后吐槽一下网上铺天盖地让我写js脚本应用全局access toke…...
逆向破解学习-登山赛车
试玩 课程中的内容 Hook代码 import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.callbacks.XC_LoadPackage;public class HookComYoDo1SkiSafari2TXYYB_01 extends HookImpl{Overridepublic String p…...
linux下实现生产者和消费者 pv操作
线程同步与线程安全 生产者和消费者特点图示理解编程实现测试结果 生产者和消费者 特点 1.解耦:因为多了一个缓冲区,所以生产者和消费者并不直接相互调用,这样生产者和消费者的代码发生变化,都不会对对方产生影响。这样其实就是把生产者和消…...
十六、遥感影像识别
1、获取遥感影像数据 或用卫星遥感数据,或用无人机低空采集,原始数据加工,最后提供CSV、Excel、GeoTIFF、ENVI等数据文件。 ENVI格式的原始数据文件可以存储多维数据,包括三维数组、二维数组、一维数组甚至标量等。这是因为ENVI格式支持不仅仅是多光谱或高光谱数据…...
【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...
基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
python爬虫——气象数据爬取
一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用: 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests:发送 …...
华为OD机试-最短木板长度-二分法(A卷,100分)
此题是一个最大化最小值的典型例题, 因为搜索范围是有界的,上界最大木板长度补充的全部木料长度,下界最小木板长度; 即left0,right10^6; 我们可以设置一个候选值x(mid),将木板的长度全部都补充到x,如果成功…...







