C++ 类基础:封装、继承、多态与多线程模板实现
前言
C++ 是一门强大的面向对象编程语言,而类(Class)作为其核心特性之一,是理解和使用 C++ 的关键。本文将深入探讨 C++ 类的基本特性,包括封装、继承和多态,同时讨论类中的权限控制,并展示如何使用类继承实现一个简单的多线程开发模板。
类的基本特性
封装(Encapsulation)
封装是面向对象编程的基本原则之一,它指的是将数据(属性)和操作数据的方法(行为)捆绑在一起,形成一个独立的单元(即类),并隐藏对象的内部实现细节,只对外提供必要的接口。
在 C++ 中,封装通过类的定义来实现。类中的成员变量通常被声明为私有(private
),而成员函数则根据需要声明为公有(public
)或保护(protected
)。外部代码只能通过公有成员函数来访问和修改类的私有成员变量,从而保证了数据的安全性和完整性。
class Rectangle {
private:double width;double height;public:// 构造函数Rectangle(double w, double h) : width(w), height(h) {}// 公有成员函数,用于设置和获取宽度void setWidth(double w) { width = w; }double getWidth() const { return width; }// 公有成员函数,用于设置和获取高度void setHeight(double h) { height = h; }double getHeight() const { return height; }// 公有成员函数,计算面积double area() const { return width * height; }
};
继承(Inheritance)
继承允许一个类(子类或派生类)继承另一个类(父类或基类)的属性和方法。这有助于代码的重用和扩展,减少了重复代码的编写。
在 C++ 中,继承通过在派生类定义中使用冒号(:
)后跟基类名来实现。派生类可以继承基类的公有和保护成员,但不能直接继承私有成员(除非通过基类的公有或保护成员函数访问)。
// 基类
class Shape {
protected:std::string color;public:Shape(const std::string& c) : color(c) {}void setColor(const std::string& c) { color = c; }std::string getColor() const { return color; }
};// 派生类
class Circle : public Shape {
private:double radius;public:Circle(const std::string& c, double r) : Shape(c), radius(r) {}double area() const { return 3.14159 * radius * radius; }
};
多态(Polymorphism)
多态是指同一个接口或方法可以根据对象的不同类型执行不同的操作。在 C++ 中,多态主要通过虚函数(Virtual Functions)和继承来实现。
虚函数允许在派生类中重写基类中的函数,当通过基类指针或引用调用虚函数时,会根据对象的实际类型调用相应的派生类函数。
class Animal {
public:virtual void makeSound() const { std::cout << "Animal sound" << std::endl; }
};class Dog : public Animal {
public:void makeSound() const override { std::cout << "Bark" << std::endl; }
};class Cat : public Animal {
public:void makeSound() const override { std::cout << "Meow" << std::endl; }
};void animalSound(const Animal& animal) {animal.makeSound(); // 根据实际类型调用相应的函数
}
类中的权限问题
在 C++ 类中,成员的访问权限由关键字 private
、protected
和 public
控制:
private
:私有成员只能在类的内部访问,外部代码无法直接访问。protected
:保护成员可以在类的内部和派生类中访问,但不能在类的外部直接访问。public
:公有成员可以在类的内部、派生类和类的外部直接访问。
合理使用这些权限关键字可以有效地控制类的接口和实现,提高代码的安全性和可维护性。
使用类继承实现多线程开发模板
下面是一个简单的多线程开发模板,使用类继承的方式实现。这个模板利用了 C++11 引入的 <thread>
库,通过定义一个基类 ThreadBase
和派生类来实现具体的线程任务。
#include <iostream>
#include <thread>
#include <vector>
#include <memory>// 线程基类
class ThreadBase {
public:virtual ~ThreadBase() = default;// 启动线程void start() {thread_ = std::make_unique<std::thread>(&ThreadBase::run, this);}// 等待线程结束void join() {if (thread_ && thread_->joinable()) {thread_->join();}}protected:// 纯虚函数,由派生类实现具体的线程任务virtual void run() = 0;private:std::unique_ptr<std::thread> thread_;
};// 派生类,实现具体的线程任务
class MyThread : public ThreadBase {
protected:void run() override {for (int i = 0; i < 5; ++i) {std::cout << "Thread running: " << i << std::endl;std::this_thread::sleep_for(std::chrono::milliseconds(500));}}
};int main() {MyThread thread;thread.start();thread.join();return 0;
}
代码说明
-
ThreadBase
类:- 定义了一个纯虚函数
run()
,要求派生类必须实现。 - 提供了
start()
和join()
方法,用于启动和等待线程结束。 - 使用
std::unique_ptr
管理std::thread
对象,确保线程资源的安全释放。
- 定义了一个纯虚函数
-
MyThread
类:- 继承自
ThreadBase
,并实现了run()
方法。 - 在
run()
方法中,打印线程运行状态并休眠一段时间,模拟线程任务。
- 继承自
-
main
函数:- 创建
MyThread
对象,调用start()
启动线程,然后调用join()
等待线程结束。
- 创建
通过这种方式,我们可以轻松地创建和管理多个线程,每个线程执行不同的任务。同时,由于使用了继承和多态,代码具有良好的扩展性和可维护性。
总结
C++ 类提供了封装、继承和多态等强大的面向对象特性,使得代码更加模块化、可重用和易于维护。合理使用类中的权限控制可以有效地保护数据的安全性和完整性。通过类继承实现多线程开发模板,可以方便地创建和管理多个线程,提高程序的并发性能。希望本文能帮助你更好地理解和使用 C++ 类。
相关文章:
C++ 类基础:封装、继承、多态与多线程模板实现
前言 C 是一门强大的面向对象编程语言,而类(Class)作为其核心特性之一,是理解和使用 C 的关键。本文将深入探讨 C 类的基本特性,包括封装、继承和多态,同时讨论类中的权限控制,并展示如何使用类…...

表单设计器拖拽对象时添加属性
背景:因为项目需要。自写设计器。遇到的坑在此记录 使用的拖拽组件时vuedraggable。下面放上局部示例截图。 坑1。draggable标签在拖拽时可以获取到被拖拽的对象属性定义 要使用 :clone, 而不是clone。我想应该是因为draggable标签比较特。另外在使用**:clone时要将…...
简单介绍C++中 string与wstring
在C中,string和wstring是两种用于处理不同字符编码的字符串类型,分别基于char和wchar_t字符类型。以下是它们的详细说明和对比: 1. 基础定义 string 类型:std::string 字符类型:char(通常为8位)…...

CSS 工具对比:UnoCSS vs Tailwind CSS,谁是你的菜?
在现代前端开发中,Utility-First (功能优先) CSS 框架已经成为主流。其中,Tailwind CSS 无疑是市场的领导者和标杆。然而,一个名为 UnoCSS 的新星正以其惊人的性能和极致的灵活性迅速崛起。 这篇文章将深入探讨这两款工具的核心理念、技术差…...
Yii2项目自动向GitLab上报Bug
Yii2 项目自动上报Bug 原理 yii2在程序报错时, 会执行指定action, 通过重写ErrorAction, 实现Bug自动提交至GitLab的issue 步骤 配置SiteController中的actions方法 public function actions(){return [error > [class > app\helpers\web\ErrorAction,],];}重写Error…...
背包问题双雄:01 背包与完全背包详解(Java 实现)
一、背包问题概述 背包问题是动态规划领域的经典问题,其核心在于如何在有限容量的背包中选择物品,使得总价值最大化。根据物品选择规则的不同,主要分为两类: 01 背包:每件物品最多选 1 次(选或不选&#…...
Python第七周作业
Python第七周作业 文章目录 Python第七周作业 1.使用open以只读模式打开文件data.txt,并逐行打印内容 2.使用pathlib模块获取当前脚本的绝对路径,并创建logs目录(若不存在) 3.递归遍历目录data,输出所有.csv文件的路径…...

Qt的学习(二)
1. 创建Hello Word 两种方式,实现helloworld: 1.通过图形化的方式,在界面上创建出一个控件,显示helloworld 2.通过纯代码的方式,通过编写代码,在界面上创建控件, 显示hello world; …...
算法刷题-回溯
今天给大家分享的还是一道关于dfs回溯的问题,对于这类问题大家还是要多刷和总结,总体难度还是偏大。 对于回溯问题有几个关键点: 1.首先对于这类回溯可以节点可以随机选择的问题,要做mian函数中循环调用dfs(i&#x…...

工厂方法模式和抽象工厂方法模式的battle
1.案例直接上手 在这个案例里面,我们会实现这个普通的工厂方法,并且对比这个普通工厂方法和我们直接创建对象的差别在哪里,为什么需要一个工厂: 下面的这个是我们的这个案例里面涉及到的接口和对应的实现类: 两个发…...
深入解析 ReentrantLock:原理、公平锁与非公平锁的较量
ReentrantLock 是 Java 中 java.util.concurrent.locks 包下的一个重要类,用于实现线程同步,支持可重入性,并且可以选择公平锁或非公平锁的实现方式。下面将详细介绍 ReentrantLock 的实现原理以及公平锁和非公平锁的区别。 ReentrantLock 实现原理 基本架构 ReentrantLo…...

鸿蒙Navigation路由导航-基本使用介绍
1. Navigation介绍 Navigation组件是路由导航的根视图容器,一般作为Page页面的根容器使用,其内部默认包含了标题栏、内容区和工具栏,其中内容区默认首页显示导航内容(Navigation的子组件)或非首页显示(Nav…...
JavaScript 标签加载
目录 JavaScript 标签加载script 标签的 async 和 defer 属性,分别代表什么,有什么区别1. 普通 script 标签2. async 属性3. defer 属性4. type"module"5. 各种加载方式的对比6. 使用建议 JavaScript 标签加载 script 标签的 async 和 defer …...
「Java基本语法」变量的使用
变量定义 变量是程序中存储数据的容器,用于保存可变的数据值。在Java中,变量必须先声明后使用,声明时需指定变量的数据类型和变量名。 语法 数据类型 变量名 [ 初始值]; 示例:声明与初始化 public class VariableDemo {publi…...

CMS内容管理系统的设计与实现:多站点模式的实现
在一套内容管理系统中,其实有很多站点,比如企业门户网站,产品手册,知识帮助手册等,因此会需要多个站点,甚至PC、mobile、ipad各有一个站点。 每个站点关联的有站点所在目录及所属的域名。 一、站点表设计…...
用鸿蒙HarmonyOS5实现国际象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的国际象棋小游戏的完整实现代码,使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├── …...

ZYNQ学习记录FPGA(二)Verilog语言
一、Verilog简介 1.1 HDL(Hardware Description language) 在解释HDL之前,先来了解一下数字系统设计的流程:逻辑设计 -> 电路实现 -> 系统验证。 逻辑设计又称前端,在这个过程中就需要用到HDL,正文…...
k8s从入门到放弃之Pod的容器探针检测
k8s从入门到放弃之Pod的容器探针检测 在Kubernetes(简称K8s)中,容器探测是指kubelet对容器执行定期诊断的过程,以确保容器中的应用程序处于预期的状态。这些探测是保障应用健康和高可用性的重要机制。Kubernetes提供了两种种类型…...
精益数据分析(98/126):电商转化率优化与网站性能的底层逻辑
精益数据分析(98/126):电商转化率优化与网站性能的底层逻辑 在电子商务领域,转化率与网站性能是决定商业成败的核心指标。今天,我们将深入解析不同类型电商平台的转化率基准,探讨页面加载速度对用户行为的…...

Java中HashMap底层原理深度解析:从数据结构到红黑树优化
一、HashMap概述与核心特性 HashMap作为Java集合框架中最常用的数据结构之一,是基于哈希表的Map接口非同步实现。它允许使用null键和null值(但只能有一个null键),并且不保证映射顺序的恒久不变。与Hashtable相比,Hash…...

【记录坑点问题】IDEA运行:maven-resources-production:XX: OOM: Java heap space
问题:IDEA出现maven-resources-production:operation-service: java.lang.OutOfMemoryError: Java heap space 解决方案:将编译的堆内存增加一点 位置:设置setting-》构建菜单build-》编译器Complier...

【阅读笔记】MemOS: 大语言模型内存增强生成操作系统
核心速览 研究背景 研究问题:这篇文章要解决的问题是当前大型语言模型(LLMs)在处理内存方面的局限性。LLMs虽然在语言感知和生成方面表现出色,但缺乏统一的、结构化的内存架构。现有的方法如检索增强生成(RA…...
Java中栈的多种实现类详解
Java中栈的多种实现类详解:Stack、LinkedList与ArrayDeque全方位对比 前言一、Stack类——Java最早的栈实现1.1 Stack类简介1.2 常用方法1.3 优缺点分析 二、LinkedList类——灵活的双端链表2.1 LinkedList类简介2.2 常用方法2.3 优缺点分析 三、ArrayDeque类——高…...
6.计算机网络核心知识点精要手册
计算机网络核心知识点精要手册 1.协议基础篇 网络协议三要素 语法:数据与控制信息的结构或格式,如同语言中的语法规则语义:控制信息的具体含义和响应方式,规定通信双方"说什么"同步:事件执行的顺序与时序…...
基于Uniapp的HarmonyOS 5.0体育应用开发攻略
一、技术架构设计 1.混合开发框架选型 (1)使用Uniapp 3.8版本支持ArkTS编译 (2)通过uni-harmony插件调用原生能力 (3)分层架构设计: graph TDA[UI层] -->|Vue语法| B(Uniapp框架)B --&g…...

【笔记】AI Agent 项目 SUNA 部署 之 Docker 构建记录
#工作记录 构建过程记录 Microsoft Windows [Version 10.0.27871.1000] (c) Microsoft Corporation. All rights reserved.(suna-py3.12) F:\PythonProjects\suna>python setup.py --admin███████╗██╗ ██╗███╗ ██╗ █████╗ ██╔════╝…...

五、jmeter脚本参数化
目录 1、脚本参数化 1.1 用户定义的变量 1.1.1 添加及引用方式 1.1.2 测试得出用户定义变量的特点 1.2 用户参数 1.2.1 概念 1.2.2 位置不同效果不同 1.2.3、用户参数的勾选框 - 每次迭代更新一次 总结用户定义的变量、用户参数 1.3 csv数据文件参数化 1、脚本参数化 …...

python基础语法Ⅰ
python基础语法Ⅰ 常量和表达式变量是什么变量的语法1.定义变量使用变量 变量的类型1.整数2.浮点数(小数)3.字符串4.布尔5.其他 动态类型特征注释注释是什么注释的语法1.行注释2.文档字符串 注释的规范 常量和表达式 我们可以把python当作一个计算器,来进行一些算术…...

C++11 constexpr和字面类型:从入门到精通
文章目录 引言一、constexpr的基本概念与使用1.1 constexpr的定义与作用1.2 constexpr变量1.3 constexpr函数1.4 constexpr在类构造函数中的应用1.5 constexpr的优势 二、字面类型的基本概念与使用2.1 字面类型的定义与作用2.2 字面类型的应用场景2.2.1 常量定义2.2.2 模板参数…...

EEG-fNIRS联合成像在跨频率耦合研究中的创新应用
摘要 神经影像技术对医学科学产生了深远的影响,推动了许多神经系统疾病研究的进展并改善了其诊断方法。在此背景下,基于神经血管耦合现象的多模态神经影像方法,通过融合各自优势来提供有关大脑皮层神经活动的互补信息。在这里,本研…...