当前位置: 首页 > news >正文

【C++】解析C++面向对象三要素:封装、继承与多态实现机制

解析C++面向对象三要素:封装、继承与多态实现机制

  • 1. 面向对象设计基石
  • 2. 封装:数据守卫者
    • 2.1 访问控制实现
    • 2.2 封装优势
  • 3. 继承:代码复用艺术
    • 3.1 继承的核心作用
    • 3.2 继承类型对比
    • 3.3 典型应用场景
    • 3.4 构造函数与析构函数处理
      • 3.4.1 构造顺序控制
      • 3.4.2 显式调用基类构造
      • 3.4.3 析构函数特性
    • 3.5 方法覆盖与名称隐藏
      • 3.5.1 函数隐藏现象
      • 3.5.2 正确实现方法覆盖
    • 3.6 多重继承与虚继承
      • 3.6.1 多重继承的内存布局
      • 3.6.2 菱形继承问题
      • 3.6.3 虚继承解决方案
    • 3.7 特殊继承场景处理
      • 3.7.1 继承中的友元关系
      • 3.7.2 final关键字使用
      • 3.7.3 空基类优化(EBCO)
    • 3.8 C++11/14/17继承增强特性
      • 3.8.1 继承构造函数
      • 3.8.2 override与final
    • 3.9 继承与模板的协作
      • 3.9.1 CRTP模式(奇异递归模板模式)
      • 3.9.2 类型特征检查
  • 4. 多态:动态绑定魔法
    • 4.1 多态的本质与分类
      • 4.1.1 多态的核心概念
      • 4.1.2 多态的应用价值
    • 4.2 虚函数机制剖析
      • 4.2.1 虚函数表(vtable)原理
      • 4.2.2 虚函数调用过程
      • 4.2.3 虚函数表构造规则
    • 4.3 虚函数重写规范详解
      • 4.3.1 有效重写条件
      • 4.3.2 现代C++重写控制
      • 4.3.3 常见重写错误
    • 4.4 多态实现话题
      • 4.4.1 动态类型识别(RTTI)
      • 4.4.2 虚函数默认参数陷阱
      • 4.4.3 纯虚函数与抽象类
    • 4.5 现代C++多态增强
      • 4.5.1 类型安全的向下转型
      • 4.5.2 基于概念的接口约束(C++20)
      • 4.5.3 多态值语义(类型擦除)
    • 4.6 最佳实践与陷阱规避
      • 4.6.1 黄金法则
      • 4.6.2 常见陷阱示例
  • 5. 总结

1. 面向对象设计基石

C++作为面向对象编程的典范语言,其核心特性封装、继承和多态构成了现代软件工程的支柱。本篇文章将剖析这三个核心特性的实现机制,着重解析多态实现的关键——虚函数系统。

2. 封装:数据守卫者

2.1 访问控制实现

C++通过访问限定符publicprotectedprivate建立严密的访问控制体系:

class Data {
private:char ch; // 完全封装
protected:short s; // 继承可见
public:int i;  // 公共可见
};

private:仅在类内可见。

protected:非继承关系,类外不可见。

public:类外可见。

2.2 封装优势

  1. 数据隐藏防止意外修改。
class Student {
private:string name;int age;
public:Student() {}Student(string name, int age) {name = name;if (age >= 18 && age < 24) {age = age; // 限制赋值在范围内}else {age = 18;}}
};int main() {Student s;s.age = 99; // 直接访问私有成员变量会报错return 0;
}
  1. 接口与实现解耦。
  2. 保持类不变量的完整性。

3. 继承:代码复用艺术

3.1 继承的核心作用

  • 代码复用:复用基类已有功能。
  • 接口扩展:在派生类中添加新特性。
  • 多态基础:构建类层次结构。

3.2 继承类型对比

继承方式基类public成员基类protected成员基类private成员
publicpublicprotected不可访问
protectedprotectedprotected不可访问
privateprivateprivate不可访问
// 基础继承类型
class Base { /*...*/ };class PublicDerived    : public Base    {};  // 公有继承
class ProtectedDerived : protected Base {};  // 保护继承
class PrivateDerived   : private Base   {};  // 私有继承// 特殊继承形式
class MultipleDerived : public Base1, public Base2 {};  // 多重继承
class VirtualDerived  : virtual public Base {};        // 虚继承

3.3 典型应用场景

公有继承(is-a关系):

class Animal { /*...*/ };
class Cat : public Animal { /*...*/ };  // 猫是动物

保护继承(实现继承):

class StackImpl { /*...*/ };
class SafeStack : protected StackImpl { // 隐藏基类接口,仅暴露安全操作
};

私有继承(has-a替代方案):

class Engine { /*...*/ };
class Car : private Engine { // 汽车使用发动机实现,但不是发动机
};

3.4 构造函数与析构函数处理

3.4.1 构造顺序控制

class Base {
public:Base() { std::cout << "Base constructor" << std::endl; }
};class Derived : public Base {
public:Derived() { std::cout << "Derived constructor" << std::endl; }
};
int main() {Derived d;return 0;
}

构造顺序控制

3.4.2 显式调用基类构造

class Base {
private:int val_;
public:Base(int val) : val_(val) {std::cout << "Base constructor" << std::endl;}
};class Derived : public Base {
public:Derived(): Base(10) { // 显式初始化基类std::cout << "Derived constructor" << std::endl;}
};
int main() {Derived d;return 0;
}
// Base constructor
// Derived constructor

3.4.3 析构函数特性

  • 基类析构函数应声明为virtual
    • 如果基类析构函数不使用virtual声明,可能会造成资源未能完全释放。
    • 严重后果:
      • **Derived::data**未被释放 → \rightarrow 内存泄漏。
        • 派生类析构函数未执行 → \rightarrow 其他资源(文件句柄、网络连接等)泄漏。
class Base {
public:~Base() { std::cout << "Base析构" << std::endl; }
};class Derived : public Base {int* data;  // 动态资源
public:Derived() : data(new int[1024]) {}~Derived() { delete[] data; std::cout << "Derived析构" << std::endl; }
};int main() {Base* obj = new Derived();delete obj;  // 只调用Base的析构函数!
}
// Base析构
// 正确处理方式
class Base {
public:virtual ~Base() {  // 关键修改std::cout << "Base析构" << std::endl; }
};class Derived : public Base {Derived() : data(new int[1024]) {}~Derived() { delete[] data; std::cout << "Derived析构" << std::endl; }
};int main() {Base* obj = new Derived();delete obj;  // 正确调用Derived析构
}
// Derived析构
// Base析构
  • 析构顺序与构造严格相反。
  • 异常处理需谨慎。

3.5 方法覆盖与名称隐藏

3.5.1 函数隐藏现象

class Base {
public:void func(int) { cout << "Base::func(int)" << endl; }
};class Derived : public Base {
public:void func(double) {cout << "Derived::func(double)" << endl;}
};int main() {Derived d;d.func(10);  // 调用Derived::func(double)d.Base::func(10);  // 显式调用基类版本
}
// Derived::func(double)
// Base::func(int)
  • 如果派生类的函数与基类的函数同名,并且参数也相同,但是基类的函数没有**virtual**声明。此时,基类的函数就会被隐藏(注意别与覆盖混淆)。

3.5.2 正确实现方法覆盖

class Shape {
public:virtual void draw() const {cout << "绘制基本形状" << endl;}
};class Circle : public Shape {
public:void draw() const override {  // C++11显式重写cout << "绘制圆形" << endl;}
};
int main() {Circle c;c.draw();  // 调用Circle的draw方法Shape* s = &c;  // 基类指针指向派生类对象s->draw();  // 调用Circle的draw方法,动态绑定return 0;
}
// 绘制圆形
// 绘制圆形

3.6 多重继承与虚继承

3.6.1 多重继承的内存布局

class BaseA { int a; };
class BaseB { int b; };
class Derived : public BaseA, public BaseB { int c; };

多重继承的内存布局

3.6.2 菱形继承问题

class CommonBase { 
public:int data; 
};
class Base1 : public CommonBase {};
class Base2 : public CommonBase {};
class Diamond : public Base1, public Base2 {};  // 数据冗余int main() {Diamond d;d.data = 10; // 编译错误,因为不清楚是Base1还是Base2的datareturn 0;
}

菱形继承问题

3.6.3 虚继承解决方案

class CommonBase { int data; };
class Base1 : virtual public CommonBase {};
class Base2 : virtual public CommonBase {};
class Diamond : public Base1, public Base2 {};int main() {Diamond d;d.data = 10;  // 唯一副本
}

虚继承实现原理:

  • 引入虚基类指针(vbptr)。
  • 共享基类子对象。
  • 增加运行时开销。

虚基类指针

3.7 特殊继承场景处理

3.7.1 继承中的友元关系

友元关系不能继承,也就是说基类友元不能访问子类私有和保护成员。

class Base {friend void friendFunction();  // 声明友元函数
private:int secret;
};class Derived : public Base {
private:int data;
};void friendFunction() {Derived d;d.secret = 10;  // 可以访问基类私有成员d.data = 10;  // 不能访问Derived私有成员
}

3.7.2 final关键字使用

final修饰的类不能被继承

class Base final {};  // 禁止被继承class Derived : public Base {};  // 编译错误class Interface {
public:virtual void func() final;  // 禁止重写
};class Impl : public Interface {void func() override;  // 编译错误
};

3.7.3 空基类优化(EBCO)

class Empty {};
class Derived : private Empty {int value;
};int main() {Derived d;cout << sizeof(d) << endl; // 4
}
// sizeof(Derived) == sizeof(int)

3.8 C++11/14/17继承增强特性

3.8.1 继承构造函数

class Base {
public:Base(int a, double d) {a_ = a;d_ = d;}
private:int a_;double d_;
};class Derived : public Base {using Base::Base;  // 继承构造函数
};

3.8.2 override与final

class Interface {
public:virtual void func() const = 0;  // 纯虚函数
};class Impl : public Interface {
public:void func() const override final {cout << "实现接口的函数" << endl;}
};

3.9 继承与模板的协作

3.9.1 CRTP模式(奇异递归模板模式)

template <typename T>
class Counter {
protected:static int count;
public:Counter() { ++count; }~Counter() { --count; }static int getCount() { return count; }
};class Widget : public Counter<Widget> {};
// 每个Widget类型独立计数

3.9.2 类型特征检查

template <typename T>
class Processor {static_assert(std::is_base_of_v<BaseInterface, T>,"必须继承自BaseInterface");// ...
};

4. 多态:动态绑定魔法

4.1 多态的本质与分类

4.1.1 多态的核心概念

多态是面向对象编程的三大特性之一,允许不同对象对同一消息做出不同响应。C++中多态主要分为两类:

  • **编译时多态:**函数重载、模板。
  • **运行时多态:**虚函数机制。

4.1.2 多态的应用价值

  • 提高代码扩展性。
  • 增强接口统一性。
  • 实现动态行为绑定。
  • 支持复杂系统设计模式。

4.2 虚函数机制剖析

4.2.1 虚函数表(vtable)原理

每个包含虚函数的类都会生成一个虚函数表,存储指向虚函数的指针:

class Animal {
public:virtual void sound() { /* ... */ }virtual ~Animal() = default;
};class Cat : public Animal {
public:void sound() override { /* ... */ }
};

内存布局示意:

Cat对象实例:
+------------------+
| vptr             | --> [Cat::sound()地址]
| Animal成员数据    |     [Animal::~Animal()地址]
| Cat特有数据       |    
+------------------+

4.2.2 虚函数调用过程

  1. 通过对象实例的vptr定位vtable
  2. 根据函数偏移量获取目标函数地址。
  3. 执行间接调用。
; x86汇编示例
mov rax, [rcx]       ; 获取vptr
call [rax+0]         ; 调用第一个虚函数

4.2.3 虚函数表构造规则

类类型vtable内容
基类基类虚函数地址
派生类重写后的函数地址,未重写的保留基类地址

4.3 虚函数重写规范详解

4.3.1 有效重写条件

  • 基类函数必须声明为virtual
  • 函数完全一致(C++11后允许返回类型协变)。
  • 访问权限可以不同(但通常不建议)。

协变返回类型示例:

class Base {
public:virtual Base* clone() const { /* ... */ }
};class Derived : public Base {
public:Derived* clone() const override { /* ... */ }  // 合法协变
};

4.3.2 现代C++重写控制

class Interface {
public:virtual void operation() = 0;virtual ~Interface() = default;
};class Implementation : public Interface {
public:void operation() override final {  // 显式标记重写并禁止进一步重写// 具体实现}
};

4.3.3 常见重写错误

  1. 参数列表不匹配:
class Base {
public:virtual void func(int) {}
};class Derived : public Base {
public:void func(double) override {}  // 错误!参数列表不匹配
};
  1. 遗漏virtual关键字:
class Base {
public:void initialize() {}  // 非虚函数
};class Derived : public Base {
public:void initialize() override {}  // 编译错误
};

4.4 多态实现话题

4.4.1 动态类型识别(RTTI)

Base* obj = new Derived();
if (auto d = dynamic_cast<Derived*>(obj)) {// 安全向下转型d->specificMethod();
}

4.4.2 虚函数默认参数陷阱

class Base {
public:virtual void show(int x = 10) {cout << "Base: " << x << endl;}
};class Derived : public Base {
public:void show(int x = 20) override {cout << "Derived: " << x << endl;}
};Base* obj = new Derived();
obj->show();  // 输出Derived: 10(默认参数静态绑定)

4.4.3 纯虚函数与抽象类

class AbstractDevice {
public:virtual void initialize() = 0;  // 纯虚函数virtual ~AbstractDevice() = default;void commonOperation() {  // 可包含具体实现// 通用操作}
};

4.5 现代C++多态增强

4.5.1 类型安全的向下转型

Base* basePtr = new Derived();
if (Derived* derivedPtr = dynamic_cast<Derived*>(basePtr)) {// 安全访问派生类成员
}

4.5.2 基于概念的接口约束(C++20)

template <typename T>
concept Drawable = requires(T t) {{ t.draw() } -> std::same_as<void>;
};void render(Drawable auto& obj) {obj.draw();
}

4.5.3 多态值语义(类型擦除)

#include <memory>
#include <functional>class AnyDrawable {struct Concept {virtual void draw() = 0;virtual ~Concept() = default;};template <typename T>struct Model : Concept {T obj;void draw() override { obj.draw(); }};std::unique_ptr<Concept> ptr;
public:template <typename T>AnyDrawable(T&& obj) : ptr(new Model<std::decay_t<T>>{std::forward<T>(obj)}) {}void draw() { ptr->draw(); }
};

4.6 最佳实践与陷阱规避

4.6.1 黄金法则

  1. 多态基类必须声明虚析构函数。
  2. 优先使用override明确重写意图。
  3. 避免在构造函数/析构函数中调用虚函数。
  4. 谨慎使用多重继承。
  5. 使用只能指针管理多态对象。

4.6.2 常见陷阱示例

切片问题:

class Base { /* 包含虚函数 */ };
class Derived : public Base { /* 添加新成员 */ };void process(Base b) { /* ... */ }Derived d;
process(d);  // 发生对象切片,丢失派生类信息

构造函数中的虚函数调用:

class Base {
public:Base() { init(); }  // 危险!virtual void init() = 0;
};class Derived : public Base {
public:void init() override { /* 此时派生类尚未构造完成 */ }
};

5. 总结

理解封装、继承、多态的底层实现机制,是写出高效C++代码的关键。虚函数系统通过vtablevptr的协作,在运行时实现动态绑定,这种设计在保持效率的同时提供了极大的灵活性。

相关文章:

【C++】解析C++面向对象三要素:封装、继承与多态实现机制

解析C面向对象三要素&#xff1a;封装、继承与多态实现机制 1. 面向对象设计基石2. 封装&#xff1a;数据守卫者2.1 访问控制实现2.2 封装优势 3. 继承&#xff1a;代码复用艺术3.1 继承的核心作用3.2 继承类型对比3.3 典型应用场景3.4 构造函数与析构函数处理3.4.1 构造顺序控…...

c语言 写一个五子棋

c语言 IsWin判赢 display 画棋盘 判断落子的坐标是否已有棋子 判断落子坐标范围是否超出范围 // 五子棋 #include <stdio.h> #include <stdlib.h>// 画棋盘 void display(char map[][10]) {system("clear");printf(" 0 1 2 3 4 5 6 7 8 9\n&…...

深度解析 IDEA 集成 Continue 插件:提升开发效率的全流程指南

一、插件核心功能与应用场景 Continue 是一款专为 JetBrains IDE 设计的 AI 编程助手插件&#xff0c;基于大语言模型实现以下核心功能&#xff1a; 智能代码生成&#xff1a;支持根据自然语言描述生成完整方法、单元测试或设计模式&#xff08;如线程安全单例模式&#xff0…...

Node.js

本文来源 &#xff1a; 腾讯元宝 Node.js 是一个基于 ​​Chrome V8 引擎​​ 的 JavaScript 运行时环境&#xff0c;采用 ​​事件驱动​​ 和 ​​非阻塞 I/O​​ 模型&#xff0c;专为构建高性能、可扩展的网络应用而设计。以下是其核心特性和应用场景的总结&#xff1a; 1…...

idea经常卡顿解决办法

一&#xff1a;前言 &#xff08;1&#xff09;使用idea工具开发过久&#xff0c;出现卡顿&#xff0c;等待响应 二&#xff1a;原因 &#xff08;1&#xff09;给idea设置的运行内存过小&#xff0c;需要使用的内存超过设置的内存 &#xff08;2&#xff09;插件过多&…...

【python】字典:: a list of dictionaries

No, actions is not a dictionary. It’s a list of dictionaries. Each item in the list is a dictionary with three key-value pairs: “measure” (number), “resource” (string), and “reason” (string). Here’s the structure: actions is a list []Each element…...

高效电脑隐私信息清理实用工具

软件介绍 本文介绍的这款Privacy Eraser&#xff0c;它是一款电脑系统隐私清理工具。 功能介绍 这款工具能够清理电脑里的多种信息&#xff0c;比如最近文件、临时文件、注册表信息&#xff0c;还有浏览器插件以及日志文件等等。 引导提示 注重隐私保护的小伙伴一定要将这款…...

在ubuntu系统中将vue3的打包文件dist 部署nginx 并且配置ssl证书 以https方式访问

在ubuntu系统中将vue3的打包文件dist 部署nginx 并且配置ssl证书 以https方式访问 确保 Nginx 已安装准备 Vue 3 打包文件配置 Nginx编辑 Nginx 配置文件启用配置文件测试 Nginx 配置重新加载 Nginx配置 SSL 证书获取 SSL 证书验证证书自动续期验证部署注意事项 确保 Nginx 已安…...

MH22D3开发高级UI应用,适配arm2d驱动

在资源有限的嵌入系统上&#xff0c;要开发出具有现代风格&#xff08;圆弧&#xff0c;表盘&#xff0c;滚动&#xff0c;滑动&#xff0c;透明&#xff0c;图层叠加等&#xff09;的UI应用&#xff0c;需要极高的cpu算力和ram&#xff0c;flash资源的支持。 但是往往鱼和熊掌…...

MongoDB数据库深度解析:架构、特性与应用场景

在现代应用程序开发中&#xff0c;数据存储技术的选择至关重要。在众多的数据库管理系统中&#xff0c;MongoDB以其灵活性和强大的功能迅速崛起&#xff0c;成为NoSQL数据库中的佼佼者。本文将深入解析MongoDB的架构、核心特性、性能优化及其在实际应用中的最佳实践&#xff0c…...

LeetCode 235. 二叉搜索树的最近公共祖先 LeetCode 701.二叉搜索树中的插入操作 LeetCode 450.删除二叉搜索树中的节点

LeetCode 235. 二叉搜索树的最近公共祖先 思路&#xff1a; 根据二叉搜索树的特性&#xff0c;对 “基于二叉树的最近公共祖先 ” 进行优化&#xff0c;在二叉树寻找最近公共祖先时&#xff0c;需要分别对根节点的两个子树进行遍历来判断两个节点是异侧还是同侧。但是在二叉搜…...

GPU异步执行漏洞攻防实战:从CUDA Stream竞争到安全编程规范

点击 “AladdinEdu&#xff0c;同学们用得起的【H卡】算力平台”&#xff0c;H卡级别算力&#xff0c;按量计费&#xff0c;灵活弹性&#xff0c;顶级配置&#xff0c;学生专属优惠。 引言 在高校实验室的GPU加速计算研究中&#xff0c;多卡并行编程已成为提升深度学习训练效…...

[c语言日寄]数据结构:栈

【作者主页】siy2333 【专栏介绍】⌈c语言日寄⌋&#xff1a;这是一个专注于C语言刷题的专栏&#xff0c;精选题目&#xff0c;搭配详细题解、拓展算法。从基础语法到复杂算法&#xff0c;题目涉及的知识点全面覆盖&#xff0c;助力你系统提升。无论你是初学者&#xff0c;还是…...

day21:零基础学嵌入式之数据结构

一、双向链表&#xff08;doulinklist&#xff09; 1. 2.创建 struct DouLinkList *CreateDouLinkList() {struct DouLinkList *dl malloc(sizeof(struct DouLinkList));if(NULL dl){fprintf(stderr, "CreateDouLinkLis malloc");return NULL;}dl->head NUL…...

数据结构之图的应用场景及其代码

一&#xff0c;最小生成树 最小生成树&#xff08;Minimum Spanning Tree, MST&#xff09;是图论中的经典问题&#xff0c;旨在通过选择无向连通图中的边&#xff0c;使得所有节点连通且总边权最小。 1.1 普里姆&#xff08;Prim&#xff09;算法 普里姆算法是一种用于求解…...

python克洛伊婚纱摄影预约管理系统

目录 技术栈介绍具体实现截图系统设计研究方法&#xff1a;设计步骤设计流程核心代码部分展示研究方法详细视频演示试验方案论文大纲源码获取/详细视频演示 技术栈介绍 Django-SpringBoot-php-Node.js-flask 本课题的研究方法和研究步骤基本合理&#xff0c;难度适中&#xf…...

GCC 使用说明

参数 -fPIC ppc_85xx-gcc -shared -fPIC liberr.c -o liberr.so -fPIC 作用于编译阶段&#xff0c;告诉编译器产生与位置无关代码(Position-Independent Code)&#xff0c; 则产生的代码中&#xff0c;没有绝对地址&#xff0c;全部使用相对地址&#xff0c;故而代码可以被加…...

配置别名路径 @

CRA本身把webpack配置包装到了黑盒里无法直接修改&#xff0c;需要借助一个插件 - craco 1. 路径解析配置&#xff08;Webpack&#xff09;-- craco 插件 把 / 解析为 src/ 配置步骤&#xff1a; 1.安装 craco npm i -D craco/craco 2. 项目根目录下创建配置文件 craco.co…...

MYSQL基本命令

目录 1.登录命令2.操作数据库命令2.1查询数据库(show)2.2 创建数据库(create)2.3使用数据库(use) 3.操作表命令3.1增加表3.2查询表3.3修改表(alert)3.4 删除(delete/drop) 1.登录命令 mysql -uroot -p2.操作数据库命令 2.1查询数据库(show) show databases;2.2 创建数据库(c…...

C#语法基础

一、什么是.NET平台 .NET 是由 Microsoft 支持的免费开放源代码应用程序平台。 .NET .NET 是一个安全、可靠且高性能的应用程序平台。C# 是 .NET 的编程语言。它是强类型且类型安全的&#xff0c;并集成了并发和自动内存管理。 C# C# 是一种新式、安全且面向对象的编程语言&…...

深度学习框架对比---Pytorch和TensorFlow

一、计算图与执行模式 1. 图的本质&#xff1a;动态图 vs 静态图 PyTorch&#xff08;动态图&#xff0c;Eager Execution&#xff09; 运行机制&#xff1a;代码逐行执行&#xff0c;张量操作立即生效&#xff0c;计算图在运行时动态构建。x torch.tensor(1.0, requires_gra…...

antdv3 Tabs.TabPane 右上角增加一个角标Badge

1、Tabs官方说明 Ant Design Vue — An enterprise-class UI components based on Ant Design and Vue.js 2、Badge角标官方效果图 Ant Design Vue — An enterprise-class UI components based on Ant Design and Vue.js 3、Tabs.TabPane要实现的效果 4、代码 <Tabs v-m…...

Python-88:英雄升级奖励

问题描述 在一个游戏中&#xff0c;小W拥有 n 个英雄&#xff0c;每个英雄的初始能力值均为 1。她可以通过升级操作来提升英雄的能力值&#xff0c;最多可以进行 k 次升级。 每次升级操作包含以下步骤&#xff1a; 选择一个英雄选择一个正整数 x将该英雄的能力值 aiai​ 更新…...

使用uv创建python项目

uv创建项目 uv init -p 3.12 qwen3env # -p 指定python版本 # qwen3env是项目名称 # 可以使用下面的步骤 mkdir qwen3env cd qwen3env uv venv -p3.12 .venv # 基于 Python 3.12 创建名为 .venv 的虚拟环境 uv init第一种方式 第二种方式 内容如下 执行python脚本 uv ru…...

window 显示驱动开发-命令和 DMA 缓冲区简介

命令和 DMA 缓冲区非常相似。 但是&#xff0c;命令缓冲区由用户模式显示驱动程序使用&#xff0c;DMA 缓冲区由显示微型端口驱动程序使用。 命令缓冲区具有以下特征&#xff1a; 它永远不会由 GPU 直接访问。 硬件供应商控制格式。 它从呈现应用程序的专用地址空间中的常规…...

深光-谷歌TV TADA/奈飞Netflix/亚马逊Prime Video/YouTube等测试外包服务

一、谷歌TV TADA测试服务 1.CTS CTS测试是一系列旨在确保设备与Android操作系统兼容性的自动化测试&#xff0c;CTS是所有测试项中测试量最大的一项测试。 2.GTS GTS测试是确保Android设备能够正确集成和运行Google Mobile Services&#xff08;GMS&#xff09;的关键步骤&am…...

《教育退费那些事儿:从困境到破局》

《教育退费那些事儿&#xff1a;从困境到破局》 教育退费&#xff1a;不容忽视的热点问题 在当今社会&#xff0c;教育消费已成为家庭支出的重要组成部分。无论是 K12 阶段的学科辅导、艺术特长培训&#xff0c;还是成人的职业技能提升、学历继续教育&#xff0c;家长和学生们…...

AtCoder 第405场初级竞赛 A~E题解

A Is it rated? 【题目链接】 原题链接:A - Is it rated? 【考点】 嵌套判断 【题目大意】 有两个分区,有不同的评分区间,给一个评分 r 和分区 x,判断是否在评分区间中。 【解析】 先判断在属于哪个分区,再判断是否在该分区评分区间中。 【难度】 GESP一级 【…...

登录接口中图片验证码Tesseract-OCR识别Java脚本

项目上移植了研发部的产品&#xff0c;文档不全&#xff0c;项目上验证码功能无法关闭&#xff0c;又要做接口/性能测试&#xff0c;开发不配合&#xff08;作为测试多么无奈&#xff09;&#xff0c;此方法识别命中率不高&#xff0c;仅作借鉴。 版本JDK11 import io.restass…...

专项智能练习(定义判断)_DA_02

2. 单选题 虚假同感偏差也叫虚假一致性偏差&#xff0c;是指人们常常会高估或夸大自己的信念、判断及行为的普遍性。在认知他人时总喜欢把自己的特性赋予他人身上&#xff0c;假定他人与自己是相同的&#xff0c;而当遇到与此相冲突的信息时&#xff0c;会坚信自己信念和判断的…...

安卓A15系统实现修改锁屏界面默认壁纸功能

最近遇到一个A15系统项目&#xff0c;客户要求修改锁屏界面的默认壁纸&#xff0c;客户提供了一张壁纸图片&#xff0c;但是从A15系统的源代码查看时才知道谷歌已经去掉了相关的代码&#xff0c;已经不支持了&#xff0c;A13和A14系统好像是支持的&#xff0c;A15系统的Wallpap…...

Linux之Yum源与Nginx服务篇

1.Yum源知识理论总结概括 Yum源概述 Yum 源 即软件仓库的标识&#xff0c;里面承载着软件包集合 Yum源组成 包含模块 【OS】、【everything】、【EPOL】、【debuginfo】、【source】、【update-source】 【os】:简称operator system 它内部包含操作系统的核心组件&#x…...

帧差法识别

定义&#xff1a; 视频通过闪过x帧画面来实现&#xff0c;帧差法就是利用两帧之间的差异找出。也就是移动目标识别 帧差法识别步骤&#xff1a; 1、灰度处理&#xff1a;将多通道变成双通道压缩图像数据。 cvtColor(before_frame,before_gray,CV_RGB2GRAY);cvtColor(after_f…...

游戏引擎学习第282天:Z轴移动与摄像机运动

运行游戏&#xff0c;展示目前进展 我们目前正在进行一个游戏开发项目。昨天&#xff0c;我们实现了基于房间的角色移动系统&#xff0c;并且加入了摄像机的跟随滚动功能。这是我们首次进入“游戏逻辑设计”阶段&#xff0c;也就是说&#xff0c;我们开始构建游戏本身的行为和…...

解决:npm install报错,reason: certificate has expired

目录 1. 问题分析2. 问题解决2.1 查看配置的镜像2.2 修改镜像源 种一棵树最好的时间是10年前&#xff0c;其次就是现在&#xff0c;加油&#xff01; --by蜡笔小柯南 1. 问题分析 启动前…...

C++ 基础知识点

1、指针和引用的区别 指针&#xff1a;是一个变量&#xff0c;存储的是另一个变量的内存地址&#xff0c;可以被重新赋值指向不同的对象&#xff0c;允许为 nullptr。 指针的特性&#xff1a; 独立变量&#xff0c;存储内存地址 可重新赋值指向其他对象 支持空值&#xff08;n…...

线代第二章矩阵第九、十节:初等变换、矩阵的标准形、阶梯形与行最简阶梯形、初等矩阵

文章目录 初等变换初等行变换初等列变换 矩阵的标准型阶梯形与行最简阶梯形阶梯型矩阵行简化阶梯形 初等矩阵定义性质初等矩阵和初等变换的联系 本节非常重要 初等变换 初等变换使用"→"&#xff0c;而不是"" 初等行变换 ① 交换两行 ② 非0数乘以某一…...

新能源汽车制动系统建模全解析——从理论到工程应用

《纯电动轻卡制动系统建模全解析&#xff1a;车速-阻力拟合、刹车力模型与旋转质量转换系数优化》 摘要 本文以纯电动轻卡为研究对象&#xff0c;系统解析制动系统建模核心参数优化方法&#xff0c;涵盖&#xff1a; 车速-阻力曲线拟合&#xff08;MATLAB实现与模型验证&…...

初始化一个Springboot项目

初始化一个Springboot项目 文章目录 初始化一个Springboot项目1、新建项目2、配置yml3、自定义异常4、通用相应类5、全局跨域配置6、总结 1、新建项目 首先&#xff0c;我们需要创建一个新的 Spring Boot 项目。这里我们使用 IntelliJ IDEA 作为开发工具&#xff0c;它提供了方…...

Springboot考研信息平台

Springboot考研信息平台 文章目录 Springboot考研信息平台1、技术栈2、项目说明3、项目截图4、核心代码4.1、前端核心代码4.2、后端核心代码 1、技术栈 前端 Vue 是一套用于构建用户界面的渐进式 JavaScript 框架。 Vue 作为前端核心框架&#xff0c;提供了响应式的数据绑定和高…...

Spring 框架 JDBC 模板技术详解

一、JDBC 模板技术概述 在传统 JDBC 开发中&#xff0c;开发人员需要手动处理数据库连接&#xff08;Connection&#xff09;、事务管理、语句执行&#xff08;Statement&#xff09;和结果集&#xff08;ResultSet&#xff09;等繁琐操作&#xff0c;不仅代码冗余度高&#x…...

Console Importer浏览器插件的编译 及 制作成.crx浏览器插件的步骤

近日由于下载Console Importer浏览器插件(一个前端调试窗口方便引下第三方库便于学习测试的插件)找不到资源&#xff0c;于是找到该插件的源码&#xff0c;地址&#xff1a;https://github.com/pd4d10/console-importer&#xff09;&#xff0c;发现该插件基于一款名为“Plasmo…...

ArcGIS切片方案记录bundle文件

文章目录 前言一、导入底图二、生成切片方案三、导出切片方案总结 前言 切片的作用是让前端可以访问地图的Mapsever来加载底图。arcgis切片是测绘人员或者WebGIs人员需要认识到的操作。 一、导入底图 首先10.8的ArcGis&#xff0c;这里没有Pro&#xff0c;Pro其实也是一样的操…...

山东大学计算机图形学期末复习6——CG10下

##CG10下 将世界坐标中的任意点 P P P 变换到以相机为中心的“观察坐标系”下&#xff08;右手坐标系&#xff09; n \mathbf{n} n&#xff1a;从相机眼睛朝向观察点的反方向&#xff0c;代表“前方”&#xff1b; u \mathbf{u} u&#xff1a;观察坐标系的 x 轴&#xff0c;向…...

【Spring Cloud Gateway】Nacos整合遇坑记:503 Service Unavailable

一、场景重现 最近在公司进行微服务架构升级&#xff0c;将原有的 Spring Cloud Hoxton 版本升级到最新的 2021.x 版本&#xff0c;同时使用 Nacos 作为服务注册中心和配置中心。在完成基础框架搭建后&#xff0c;我使用 Spring Cloud Gateway 作为API 网关&#xff0c;通过 N…...

[Linux]从零开始的STM32MP157 Busybox根文件系统测试及打包

一、前言 在上一篇教程中&#xff0c;我们成功编译了Busybox根文件系统并且能够正常使用&#xff0c;但是大家应该也发现了我们构建的根文件系统存在许多问题&#xff0c;比如一些找不到文件的报错。并且在实际的产品中一般都是将根文件系统烧录到EMMC中&#xff0c;并不是像我…...

【Pandas】pandas DataFrame eval

Pandas2.2 DataFrame Computations descriptive stats 方法描述DataFrame.abs()用于返回 DataFrame 中每个元素的绝对值DataFrame.all([axis, bool_only, skipna])用于判断 DataFrame 中是否所有元素在指定轴上都为 TrueDataFrame.any(*[, axis, bool_only, skipna])用于判断…...

考研408《计算机组成原理》复习笔记,第二章(2)数值数据的表示和运算(浮点数篇)

一、回顾定点数知识点 ——定点小数机器码表示 ——定点整数机器码表示 ——【原码】和【移码】的作用 二、浮点数表示 1、概念引入 我们生活中有很多 “带小数”&#xff0c;也就是浮点数&#xff0c;也就是【整数部分】和【纯小数部分】都不为0&#xff0c;那么这样的小数…...

【虚幻引擎】UE5独立游戏开发全流程(商业级架构)

本套课程我将会讲解一下知识 1.虚幻引擎的常用功能节点、模块包含但不限于动画模块、UI模块、AI模块、碰撞模块、伤害模块、背包模块、准心模块、武器模块、可拾取物品模块、死亡等模块。 2.整个游戏的设计思路&#xff08;游戏架构&#xff09;&#xff0c;本套教程讲解了如…...

大语言模型 08 - 从0开始训练GPT 0.25B参数量 - MiniMind 单机多卡 torchrun deepspeed

写在前面 GPT&#xff08;Generative Pre-trained Transformer&#xff09;是目前最广泛应用的大语言模型架构之一&#xff0c;其强大的自然语言理解与生成能力背后&#xff0c;是一个庞大而精细的训练流程。本文将从宏观到微观&#xff0c;系统讲解GPT的训练过程&#xff0c;…...