从零到一学习c++(基础篇--筑基期十一-类)
从零到一学习C++(基础篇) 作者:羡鱼肘子
温馨提示1:本篇是记录我的学习经历,会有不少片面的认知,万分期待您的指正。
温馨提示2:本篇会尽量用更加通俗的语言介绍c++的基础,用通俗的语言去解释术语,但不会再大白话了哦。常见,常看,常想,渐渐的就会发现术语也是很简单滴。
温馨提示3:看本篇前可以先了解前篇的内容,知识体系会更加完整哦。
从零到一学习c++(基础篇--筑基期十-函数)-CSDN博客
温馨提示4:这部分内容只是入门c++类的一个预览,就基础阶段而言应该是够用的,学习的重心在于了解
类 (Class)
类(Class)是C++面向对象编程(OOP)的核心,相当于设计图纸,用来创建具有特定属性和行为的对象。
那么什么是面向对象编程(OOP呢?
在这我们抛开传统的术语,从日常生活的角度重新解读面向对象编程(OOP)
1. 角色扮演游戏:把代码变成「游戏角色」
想象我们在开发一款 RPG 游戏,每个角色都有自己的属性和技能:
类(Class) = 角色模板
比如「战士」「法师」的职业模板,定义了他们默认的血量、攻击方式。对象(Object) = 具体的游戏角色
比如你创建了一个叫「亚瑟」的战士,他的等级、装备都是独特的。封装(Encapsulation) = 角色的隐私保护
角色的背包里有什么装备,其他角色不能直接翻看,必须通过「交易」或「查看」方法交互。继承(Inheritance) = 职业继承通用能力
「战士」和「法师」都继承了「玩家角色」的基础属性(比如移动、说话),但各自扩展了专属技能。多态(Polymorphism) = 同一技能的不同效果
所有角色都有「攻击」技能,但战士用剑砍,法师放火球,效果完全不同。
2. 乐高积木:模块化拼装代码
把编程想象成拼乐高:
类(Class) = 积木的模具
比如一个「轮子模具」,可以生产无数个轮子(对象)。对象(Object) = 具体的积木块
用轮子模具造出 4 个轮子,装到一辆车上。组合(Composition) = 用积木拼装复杂结构
车 = 轮子 + 车身 + 引擎,每个部分独立开发,最后组合成整体。接口(Interface) = 积木的拼接规则
所有能连接到车身的积木,必须有一个「卡扣接口」,不管它是轮子还是翅膀。
3. 自然界:生物学中的 OOP 思维
用生物进化理解 OOP:
类(Class) = 物种分类
比如「猫科动物」的定义:有爪子、会捕猎。对象(Object) = 个体生物
你家的橘猫「大胖」,是「猫科动物」类的一个实例。继承(Inheritance) = 遗传与变异
老虎继承了猫科动物的基础特征,但变异出了条纹皮毛。多态(Polymorphism) = 生存策略的多样性
所有动物都要「觅食」,但老鹰抓鱼,羚羊吃草,行为完全不同。
那到底为什么要用 OOP呢?
现实映射:代码结构和现实世界一致,人类更容易理解(比如游戏角色、公司员工)。
分工合作:像流水线一样,不同程序员负责不同类,最后组装成大系统。
减少重复:公共功能写在父类,子类直接复用(比如所有员工都要打卡)。
灵活扩展:新增功能像「打补丁」,不影响原有代码(比如给游戏角色加一个新技能)。
一句话总结:
OOP 是把复杂问题拆解成一个个「活的对象」,让代码像现实世界一样,通过分工、协作、进化来解决问题。
一、类的基础:封装与抽象(抽象会放到下一个阶段介绍)
1. 类是什么?
类的定义通常包括以下部分:
-
数据成员:类的属性,用于存储对象的状态。
-
成员函数:类的行为,用于操作数据成员或执行其他任务。
-
访问控制:通过
public
、private
和protected
关键字控制成员的访问权限。
详细解释--访问控制
public:公有成员可以在类的外部访问。
private:私有成员只能在类的内部访问。
protected:保护成员可以在类的内部和派生类中访问。
-
类就像汽车的设计图纸,定义了汽车的组成部分(属性)和功能(方法)。
-
代码示例:
class Car { public:// 属性(成员变量)string brand;int speed;// 方法(成员函数)void accelerate() { speed += 10; }void brake() { speed = 0; } };
2. 封装:隐藏细节,暴露接口
-
驾驶员不需要知道发动机如何工作,只需踩油门(调用方法)。
-
访问控制:
-
public
:对外公开(如油门、刹车)。 -
private
:内部细节(如发动机、电路)。
class BankAccount { private:double balance; // 私有属性,外部无法直接访问 public:void deposit(double amount) { balance += amount; } // 公开方法 };
-
3.类与结构体(struct
)
-
class
默认成员为private
,struct
默认成员为public
。 -
现代C++中,
struct
常用于仅包含数据的简单类型(POD类型)。
二、构造函数与析构函数
1. 构造函数:对象的“出生证明”
-
作用:初始化对象属性。
-
默认构造函数:无参数或参数有默认值。
-
委托构造函数(C++11):复用其他构造函数的代码。
class Student { public:Student() : Student("匿名", 18) {} // 委托构造函数Student(string name, int age) : name(name), age(age) {} private:string name;int age; };
2. 析构函数:对象的“临终清理”
-
作用:释放对象占用的资源(如内存、文件句柄)。
-
现代C++技巧:用智能指针(
unique_ptr
/shared_ptr
)替代手动资源管理。class FileHandler { public:FileHandler(const string& filename) {file = fopen(filename.c_str(), "r");}~FileHandler() { if (file) fclose(file); } // 析构时关闭文件 private:FILE* file; };
三、类的进阶特性
1. 移动语义(C++11)
-
问题:传统拷贝构造效率低(深拷贝大对象)。
-
解决:“偷”临时对象(右值)的资源,避免拷贝。
class DynamicArray { public:// 移动构造函数DynamicArray(DynamicArray&& other) noexcept : data_(other.data_), size_(other.size_) {other.data_ = nullptr; // 原对象置空other.size_ = 0;} private:int* data_;size_t size_; };
2. constexpr
成员函数(C++11)
-
作用:编译期求值的函数,用于常量表达式。
class Circle { public:constexpr Circle(double r) : radius(r) {}constexpr double area() const { return 3.14 * radius * radius; } private:double radius; };constexpr Circle c(5.0); constexpr double a = c.area(); // 编译期计算面积
3. 类成员的默认和删除(C++11)
-
默认函数:显式要求编译器生成默认实现。
-
删除函数:禁用某些函数(如拷贝构造)。
class NonCopyable { public:NonCopyable() = default;NonCopyable(const NonCopyable&) = delete; // 禁止拷贝 };
四、继承与多态
1. 继承:从基类“遗传”特性
-
电动汽车(子类)继承汽车(基类)的基本属性,并增加电池特性。
class ElectricCar : public Car { public:void charge() { battery = 100; } private:int battery; };
2. 多态:同一接口,不同实现
-
虚函数:基类声明
virtual
,子类用override
重写(C++11)。class Shape { public:virtual double area() const = 0; // 纯虚函数(抽象类) };class Circle : public Shape { public:double area() const override { return 3.14 * r * r; } // 重写 private:double r; };
五、现代C++最佳实践
1. 用 override
和 final
明确意图(C++11)
-
override
:显式标记重写虚函数,避免拼写错误。 -
final
:禁止子类进一步重写。class Base { public:virtual void func() {} };class Derived : public Base { public:void func() override final {} // 正确重写,且禁止子类重写 };
2. 委托构造与继承构造(C++11)
-
继承构造函数:复用基类构造函数。
class Base { public:Base(int x) { /*...*/ } };class Derived : public Base { public:using Base::Base; // 继承基类构造函数 };
3. 智能指针管理资源
-
unique_ptr
:独占资源所有权。 -
shared_ptr
:共享资源所有权。class Project { public:void addMember(const shared_ptr<Member>& m) {members.push_back(m);} private:vector<shared_ptr<Member>> members; };
六、综合示例:现代C++类的设计(体会一下这种风格就好,目前这是了解的内容)
#include <iostream>
#include <memory>
#include <vector>// 基类:图形
class Shape {
public:virtual double area() const = 0; // 纯虚函数virtual ~Shape() = default; // 虚析构函数(C++11)
};// 派生类:圆形
class Circle : public Shape {
public:constexpr Circle(double r) noexcept : radius(r) {}double area() const override { return 3.14 * radius * radius; }
private:double radius;
};// 图形管理器(RAII管理资源)
class ShapeManager {
public:void addShape(std::unique_ptr<Shape> shape) {shapes.push_back(std::move(shape));}void printAreas() const {for (const auto& s : shapes) {std::cout << "面积: " << s->area() << std::endl;}}
private:std::vector<std::unique_ptr<Shape>> shapes;
};int main() {ShapeManager manager;manager.addShape(std::make_unique<Circle>(5.0)); // C++14的make_uniquemanager.printAreas();return 0;
}
七、总结:类的设计原则(建议熟悉哦,以后会经常用到的)
-
高内聚低耦合:每个类专注单一职责,减少依赖。
-
优先使用组合:通过组合其他类构建功能,而非过度继承。
-
资源管理:用RAII(如智能指针)替代手动
new
/delete
。 -
拥抱现代特性:移动语义、
override
、constexpr
等提升代码质量。
小贴士:类就是自己的“代码乐高积木”,设计得越清晰、模块化,程序越容易维护和扩展!
从零到一学习c++(基础篇--筑基期)结语
自此,我们c++的基础篇--筑基期部分就结束了,通过筑基期的学习我们对c++的一些基础知识有了概要性的了解,但是让我们独自去开发某一个项目的话,是不是感觉还是比较困难的呢? 不要灰心,因为我们还没有真正入门。欧克,趁热打铁,开始从零到一学习c++(基础篇--入门期)的学习吧!!!通过从零到一学习c++(基础篇--入门期)的学习,我们就可以比较轻松的实现一些小的项目和小部分大型工程啦。
相关文章:
从零到一学习c++(基础篇--筑基期十一-类)
从零到一学习C(基础篇) 作者:羡鱼肘子 温馨提示1:本篇是记录我的学习经历,会有不少片面的认知,万分期待您的指正。 温馨提示2:本篇会尽量用更加通俗的语言介绍c的基础,用通俗的语言去…...
Java String 类
Java String 类常用方法详解 在 Java 编程里,字符串操作十分常见,而 String 类作为 Java 标准库的核心类,用于表示不可变的字符序列。任何对字符串的修改操作都会返回一个新的字符串对象,不会改变原始字符串。本文将详细介绍 Str…...

P8665 [蓝桥杯 2018 省 A] 航班时间
P8665 [蓝桥杯 2018 省 A] 航班时间 题目代码分析 题目 代码 #include <iostream> #include <vector> #include <string> #include <algorithm> #include <math.h> #include <queue>#include <cctype> using namespace std; int t;…...
Vue3项目与pnpm使用教程
文章目录 Vue3项目与pnpm使用教程一、pnpm简介二、安装pnpm三、创建Vue3项目四、运行Vue3项目五、管理项目依赖六、配置pnpm七、使用pnpm的额外功能八、总结 Vue3项目与pnpm使用教程 一、pnpm简介 pnpm是一个高性能的Node.js包管理工具,相较于npm和yarn࿰…...
C++初阶——简单实现list
目录 1、前言 2、List.h 3、Test.cpp 1、前言 1. 简单实现std::list,重点:迭代器,类模板,运算符重载。 2. 并不是,所有的类,都需要深拷贝,像迭代器类模板,只是用别的类的资源&am…...

C/C++后端开发面经
字节跳动 客户端开发 实习 一面(50min) 自我介绍是否愿意转语言,是否只愿意搞后端选一个项目来详细谈谈HTTP和HTTPS有什么区别?谈一下HTTPS加密的具体过程: 非对称加密 对称加密 证书认证的方式 非对称加密是为了保证对称密钥的安全性。 对称…...

linux 编辑器
1.三种模式 2.图例 3.wq 4.光标的使用...

【事件驱动框架OSAL】二.消息的管理机制
OSAL消息管理机制 二、消息管理机制2.1 消息的数据结构2.2 消息内存分配2.3 消息的接收和销毁2.3 源码链接地址 二、消息管理机制 在上一篇文中提到,系统消息事件(SYS_EVENT_MSG)用于任务间传递数据,而消息队列是这种机制的基础&…...
《论多源数据集成及应用》审题技巧 - 系统架构设计师
论多源数据集成及应用写作框架 一、考点概述 本论题“论多源数据集成及应用”主要考察的是计算机软件测试工程师在数据管理和集成方面的专业知识与实践能力。论题聚焦于信息爆炸时代企业、组织和个人所面临的数据挑战,特别是如何有效地收集、整理和清洗来自不同渠…...

【企业微信开发工具,获取位置】
微信开发者工具获取位置失败 报错原因解决方案 报错原因 getLocation:fail, the permission value is offline verifying解决方案 在开发工具栏输入链接,进行位置获取获取成功后,重新进入调用获取位置的页面即可如下图:...
HTML之JavaScript DOM编程获取元素的方式
HTML之JavaScript DOM编程获取元素的方式 1.获得document DOM树window.document(是window的属性)2.从document中获取要操作的元素1.直接获取var aaa document.getElementById("username") // 根据元素的id值获取页面上的唯一一个元素,有同名的则返回找到的第一个var…...
如何安装vm和centos
以下是在VMware中安装CentOS的一般步骤: 一、安装VMware 以下是在 Windows 系统中安装 VMware 软件的详细步骤: 1. 下载 VMware 软件: - 访问 VMware 官方网站(https://www.vmware.com/)。 - 根据您的操作系统选择合…...

docker 安装redis 7.4.2并挂载配置文件以及设置密码
文章目录 docker 安装redis 7.4.2下载 redis如果你喜欢使用最新的版本创建挂载redis 配置文件创建容器 docker 安装redis 7.4.2 截至2025年2月21日,Redis的最新稳定版本是 7.4.2。 下载 redis 如果你想拉取Redis的特定版本(例如最新的稳定版本 7.4.2&a…...

计算机毕业设计SpringBoot+Vue.js在线教育系统(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
Linux-C-函数栈-SP寄存器
sp(Stack Pointer,栈指针)是计算机体系结构中一个非常重要的寄存器,下面将详细介绍其作用和原理。 作用 1. 管理栈内存 栈是一种后进先出(LIFO,Last In First Out)的数据结构,在程…...
vi的基本使用
vi 是 Unix/Linux 系统中最常用的文本编辑器之一,功能强大但学习曲线较陡。以下是 vi 的基本使用方法: --- ### **1. vi 的两种模式** - **命令模式(Command Mode)**: - 默认进入的模式,用于执行命令&a…...

clickhouse--表引擎的使用
表引擎决定了如何存储表的数据。包括: 数据的存储方式和位置,写到哪里以及从哪里读取数据。(默认是在安装路径下的 data 路径)支持哪些查询以及如何支持。(有些语法只有在特定的引擎下才能用)并发数据访问。索引的使用࿰…...
LeetCode刷题零碎知识点整理
系列博客目录 文章目录 系列博客目录 数组变量有length属性,String类的对象有length()方法。String s; s.split("\\s");不能去除头部空格,需要使用s s.trim();String类的对象有toCharArray()方法,List<>类型有toArray()方法…...
GLTFLoader.js和OrbitControls.js两个 JavaScript 文件都是 Three.js 生态系统中的重要组成部分
GLTFLoader.js和OrbitControls.js两个 JavaScript 文件都是 Three.js 生态系统中的重要组成部分: 1. GLTFLoader.js 作用 GLTFLoader.js 是 Three.js 库中的一个辅助加载器脚本,其主要功能是加载 GLB 或 GLTF 格式的 3D 模型。GLTF(GL Tra…...
大厂数据仓库数仓建模面试题及参考答案
目录 什么是数据仓库,和数据库有什么区别? 数据仓库的基本原理是什么? 数据仓库架构是怎样的? 数据仓库分层(层级划分),每层做什么?分层的好处是什么?数据分层是根据什么?数仓分层的原则与思路是什么? 数仓建模常用模型有哪些?区别、优缺点是什么?星型模型和雪…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...

MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
LRU 缓存机制详解与实现(Java版) + 力扣解决
📌 LRU 缓存机制详解与实现(Java版) 一、📖 问题背景 在日常开发中,我们经常会使用 缓存(Cache) 来提升性能。但由于内存有限,缓存不可能无限增长,于是需要策略决定&am…...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...