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

C++面向对象编程学习

C++面向对象编程学习

  • 前言
  • 一、C++面向对象编程
  • 二、知识点学习
    • 1. 定义一个类
      • 1.1 使用struct定义
      • 1.2 使用class定义
      • 1.3 struct和class的区别
    • 2. 类的定义方式
      • 2.1 单文件定义(Inline Definition)
      • 2.2 分离定义(Separate Definition)
      • 2.3 头文件守卫
    • 3. 访问修饰符
    • 4. 构造函数与析构函数
      • 4.1 构造函数(Constructor)
      • 4.2 析构函数(Destructor)
    • 5. this指针
    • 6. 虚函数
    • 7. 继承
    • 8. 其余内容
  • 总结


前言

注意:本文只适合有C++基础的朋友食用!另本文章目的在于记录学习C++面向编程学习的过程,会引用到其他人的文章。
推荐文章:【C++核心】一文理解C++面向对象(超级详细!)(作者:数据知道)


一、C++面向对象编程

先由一段C++面向对象编程的典例的代码引入学习:

#include <iostream>
#include <string>// 基类:Animal
class Animal {
public: // 访问权限// 构造函数Animal(std::string name) : name_(name) {}// 虚析构函数virtual ~Animal() {}// 虚函数,用于发声virtual void makeSound() const = 0; // 纯虚函数// 打印动物的名字void printName() const {std::cout << "My name is " << name_ << std::endl;}protected:std::string name_; // 动物的名字
};// 派生类(子类):Dog
class Dog : public Animal {
public:// 构造函数Dog(std::string name) : Animal(name) {}// 实现基类的纯虚函数void makeSound() const override {std::cout << name_ << " says: Bark!" << std::endl;}
};// 派生类:Cat
class Cat : public Animal {
public:// 构造函数Cat(std::string name) : Animal(name) {}// 实现基类的纯虚函数void makeSound() const override {std::cout << name_ << " says: Meow!" << std::endl;}
};// 函数模板,用于处理任何类型的Animal
template <typename AnimalType>
void makeAnimalSound(const AnimalType& animal) {animal.makeSound();
}int main() {Dog dog("Rex");Cat cat("Whiskers");dog.printName();dog.makeSound();cat.printName();cat.makeSound();// 使用模板函数makeAnimalSound(dog);makeAnimalSound(cat);return 0;
}

二、知识点学习

1. 定义一个类

在C++中,structclass关键字都可以用来定义一个类,但它们在默认的访问权限上有所不同。以下是使用structclass定义同一个类的例子:

1.1 使用struct定义

struct MyStruct {int publicData; // 默认为publicprivate:int privateData; // 私有成员public:MyStruct(int value) : privateData(value) {}int getPrivateData() const {return privateData;}void setPrivateData(int value) {privateData = value;}private:void privateMethod() {// 私有方法}
};

1.2 使用class定义

class MyClass {int publicData; // 默认为privateprivate:int privateData; // 私有成员public:MyClass(int value) : privateData(value) {}int getPrivateData() const {return privateData;}void setPrivateData(int value) {privateData = value;}private:void privateMethod() {// 私有方法}
};

1.3 struct和class的区别

  • struct中,如果没有指定访问修饰符,成员默认是public的。
  • class中,如果没有指定访问修饰符,成员默认是private的。

从C++11起,你可以使用struct来定义一个简单的数据结构(没有或很少的行为),而class通常用于定义具有封装、继承和多态特性的对象(强调一个类型是具有封装、继承和多态的对象)。然而,这只是一个编程习惯上的区分,技术上你可以使用任何一个关键字来定义任何类型的类。

2. 类的定义方式

在C++中,类的定义通常有两种主要方式:一种是在单个文件中定义类的全部内容,另一种是将类的声明(通常称为头文件)和定义(通常称为源文件)分开。

  • 单文件定义:通常用于小型项目或简单的类,其中类的实现非常简短,或者为了减少编译依赖。
  • 分离定义:通常用于大型项目或复杂的类,其中需要隐藏实现细节,提高代码的可维护性和可读性。

2.1 单文件定义(Inline Definition)

在这种方式中,类的定义被直接放在头文件中,通常是在.h.hpp扩展名的文件中。这种方式被称为内联定义或头文件中的定义。

示例:

// MyClass.h
#ifndef MYCLASS_H
#define MYCLASS_Hclass MyClass {
public:void function() {// 实现细节}
private:int data;
};#endif // MYCLASS_H

在这种方式中,每次包含头文件时,类的定义都会被包含到使用它的每个源文件中。这可能会导致代码重复,但可以减少编译依赖和提高编译速度。

2.2 分离定义(Separate Definition)

就是类的声明放在头文件(.h.hpp),类的(定义)实现放在源文件(.cpp)。

头文件( MyClass.h ):

// MyClass.h
#ifndef MYCLASS_H
#define MYCLASS_Hclass MyClass {
public:void function();
private:int data;
};#endif // MYCLASS_H

源文件( MyClass.cpp ):

// MyClass.cpp
#include "MyClass.h"void MyClass::function() {// 实现细节data = 42; // 访问私有成员
}

在这种方式中,类的实现被隐藏在源文件中,只有声明被包含在其他文件中。这样做的好处是增加了模块化,减少了重复代码,并且使得单个类的定义更容易维护。

2.3 头文件守卫

这段代码是C++预处理器指令,用于防止头文件被多次包含,这是一种常见的头文件保护技术。这种技术被称为“包含保护”或“头文件守卫”。下面是每个指令的解释:

  1. #ifndef MYCLASS_H - 这个指令检查一个宏(在这个例子中是MYCLASS_H)是否还未定义。#ifndef是“if not defined”的缩写。如果MYCLASS_H没有定义,那么预处理器会继续处理下面的代码。

  2. #define MYCLASS_H - 这个指令定义了MYCLASS_H宏。这样,如果这个头文件被包含多次,预处理器会记住MYCLASS_H已经被定义了,并且跳过第二次及后续的包含。

  3. #endif // MYCLASS_H - 这个指令标记了预处理条件块的结束。#endif指示预处理器停止处理条件块。注释// MYCLASS_H是为了提供额外的信息,说明这个#endif与哪个#ifndef配对。这是一个编程习惯,有助于在阅读代码时快速识别匹配的指令。

包含保护的目的是防止头文件的内容被编译多次,这可能发生在多个源文件都包含了同一个头文件的情况下。如果没有包含保护,每次头文件被包含时,它的代码都会被重新编译,这不仅会导致编译错误(如重复定义),还可能降低编译效率。

例如,如果你有以下头文件和源文件结构:

// MyClass.h
#ifndef MYCLASS_H
#define MYCLASS_Hclass MyClass {// 类的定义
};#endif // MYCLASS_H// main.cpp
#include "MyClass.h"
#include "MyClass.h" // 第二次包含相同的头文件int main() {MyClass myObject;// 使用myObject
}

在没有包含保护的情况下,MyClass的定义会被包含两次,导致编译器报错,因为它尝试定义同一个类两次。有了包含保护,预处理器会识别出第二次包含是重复的,并忽略它,从而避免编译错误。

请注意,#endif指令前的注释// MYCLASS_H是可选的,但它有助于在阅读代码时快速定位匹配的#ifndef指令。

3. 访问修饰符

(1)public--------公共的,类外部可以访问;
(2)protected—保护的,类外部不可以访问;
(3)private-------私有的,类外部不能访问;

解析:

  1. public(公共的)

    • 类外部可以访问:类的公共成员在定义类的外部是可见的,可以直接通过类的实例来访问。
    • 示例
      class MyClass {
      public:int publicData; // 公共成员,可以直接访问void publicMethod() {} // 公共成员函数,可以直接调用
      };MyClass obj;
      obj.publicData = 10; // 直接访问公共成员变量
      obj.publicMethod(); // 直接调用公共成员函数
      
  2. protected(保护的)

    • 类外部不可以访问:类的受保护成员在定义类的外部是不可见的,不能直接通过类的实例来访问。
    • 但可以在派生类中访问:如果一个类派生自具有受保护成员的基类,那么这些受保护的成员在派生类中是可见的。
    • 示例
      class Base {
      protected:int protectedData; // 受保护成员,不能直接访问
      };class Derived : public Base {
      public:void accessBaseMembers() {protectedData = 20; // 在派生类中可以访问基类的受保护成员}
      };Derived obj;
      // obj.protectedData = 20; // 错误:在类外部不能直接访问受保护成员
      obj.accessBaseMembers(); // 正确:通过派生类的公共接口访问基类的受保护成员
      
  3. private(私有的)

    • 类外部不能访问:类的私有成员在定义类的外部是不可见的,不能直接通过类的实例来访问。
    • 类内部可以访问:私有成员只能在定义它们的类内部被访问,包括类的成员函数和友元类或友元函数。
    • 示例
      class MyClass {
      private:int privateData; // 私有成员,不能直接访问void privateMethod() {} // 私有成员函数,不能直接调用public:void publicMethod() {privateData = 30; // 在类内部可以访问私有成员privateMethod(); // 在类内部可以调用私有成员函数}
      };MyClass obj;
      // obj.privateData = 30; // 错误:在类外部不能直接访问私有成员
      // obj.privateMethod(); // 错误:在类外部不能直接调用私有成员函数
      obj.publicMethod(); // 正确:通过公共成员函数间接访问私有成员
      

4. 构造函数与析构函数

在C++中,构造函数和析构函数是特殊的成员函数,它们分别用于初始化对象和清理对象使用资源。
构造函数:主要作用在于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无须手动调用。语法格式如下:
构造函数语法:类名(){}

析构函数:主要作用在于对象销毁前系统自动调用,执行一些清理工作。语法格式如下:
析构函数语法: ~类名(){}

4.1 构造函数(Constructor)

构造函数是一种特殊的成员函数,用于创建类的对象时初始化对象。它具有与类相同的名称,且没有返回类型,也不能被声明为constvolatilestatic。构造函数可以有参数,也可以没有参数(无参数构造函数),可以有多个构造函数(构造函数重载),以适应不同的初始化需求。

特点

  • 没有返回值,也不抛出异常(除了析构函数外)。
  • 可以有0个或多个参数。
  • 可以有默认参数。
  • 可以被重载以提供不同的初始化方式。

示例

class MyClass {
public:// 无参数的构造函数MyClass() {// 初始化代码}// 带参数的构造函数MyClass(int value) {// 使用参数value进行初始化}// 带多个参数的构造函数MyClass(int value, const std::string& name) {// 使用参数value和name进行初始化}
};

4.2 析构函数(Destructor)

析构函数是一种特殊的成员函数,用于对象生命周期结束时执行清理工作。它用于释放对象在生命周期中分配的资源,如动态分配的内存、文件句柄、网络连接等。析构函数的名称是在类名前加上波浪号(~),且析构函数不能有参数,不能有返回值,也不能被重载。

特点

  • 没有返回值。
  • 不能带有参数。
  • 不能被重载。
  • 一个类只能有一个析构函数。

示例

class MyClass {
public:// 构造函数MyClass() {// 分配资源,如动态内存}// 析构函数~MyClass() {// 释放资源,如动态内存}
};

在上述示例中,当使用new创建MyClass对象时,会调用构造函数进行初始化。当对象不再需要时,比如超出作用域或者使用delete时,会调用析构函数进行清理。

5. this指针

在C++中,this 指针是一个特殊的指针,它在每个非静态成员函数内部可用。this 指针指向调用成员函数的对象本身,它允许成员函数访问对象的数据成员和成员函数。
作用

  1. 访问对象的成员:成员函数经常需要访问调用它的那个对象的成员变量和其他成员函数。this 指针使得成员函数能够区分不同的对象,即使它们拥有相同的成员名称。

  2. 链式调用this 指针可以用来返回对象本身,从而实现链式调用。

  3. 区分成员变量和局部变量:当成员函数中的局部变量与类的成员变量同名时,this 指针可以用来区分它们。

示例

class MyClass {int value;public:MyClass(int val) : value(val) {}int getValue() const {return value; // 使用this指针访问成员变量}MyClass& set(int val) { // 成员函数返回对象的引用this->value = val;return *this; // 使用this指针返回对象本身}void printValue() const {int localValue = 10; // 局部变量int* memVarPtr = &this->value; // 使用this指针区分成员变量和局部变量int* localVarPtr = &localValue;// 输出指针地址以区分成员变量和局部变量std::cout << "Member variable value: " << *memVarPtr << std::endl;std::cout << "Local variable value: " << *localVarPtr << std::endl;}
};int main() {MyClass obj(100);obj.printValue(); // 输出对象的成员变量和局部变量的值obj.set(200).set(300).set(400); // 链式调用std::cout << "Final value: " << obj.getValue() << std::endl; // 输出最终值return 0;
}

注意事项

  • this 指针在静态成员函数中不可用,因为静态成员函数不依赖于具体的对象实例。
  • this 指针在普通成员函数中是隐式定义的,不需要声明。
  • this 指针通常不需要手动管理,但了解其存在和作用对于编写更清晰和更有效的代码是有帮助的。
  • 在异常情况下,如果成员函数被非法调用(例如,在一个未初始化的对象上),this 指针可能不是一个有效的指针,因此在处理异常和错误时需要小心。

6. 虚函数

语法格式:

virtual ReturnType FunctionName(Parameters) {// 函数实现
}

这里的virtual关键字告诉编译器这个函数是虚函数,可以被子类重写。

当通过基类指针或引用调用虚函数时,如果对象实际是派生类的实例,那么将调用派生类中的版本,这就是多态。如果对象是基类实例,则调用基类中的版本。

例如:

class Base {
public:virtual void show() {cout << "Base class show()" << endl;}
};class Derived : public Base {
public:void show() override { // C++11中引入了override关键字来明确指出函数重写了基类中的虚函数cout << "Derived class show()" << endl;}
};int main() {Base* b;Derived d;b = &d; // 基类指针指向派生类对象b->show(); // 输出Derived class show(),展示了多态性return 0;
}

在这个例子中,尽管b是基类Base的指针,但由于它指向的是派生类Derived的对象,所以调用的实际上是Derived类中的show方法。

7. 继承

语法:class A : public B;
MyFrame::MyFrame() 表示MyFrame()是MyFrame的构造函数。
继承的主要优点包括:

  1. 代码重用:可以减少代码冗余,提高开发效率。
  2. 扩展性:可以基于现有的类进行扩展,增加新的功能。
  3. 维护性:修改基类会影响到所有派生类,简化了维护工作。

在C++中,继承是通过在类定义时使用:和继承类型关键字(如public, protected, private)来实现的。例如:

class Base {
public:void show() {cout << "Base class show()" << endl;}
};class Derived : public Base { // 使用public继承
public:void display() {cout << "Derived class display()" << endl;}
};int main() {Derived d;d.show(); // 继承自Base类的show方法d.display(); // Derived类特有的display方法return 0;
}

在这个例子中,Derived类通过public关键字继承了Base类。这意味着Derived类的对象可以访问Base类中所有公有的成员。

继承类型关键字决定了基类成员在派生类中的访问级别:

  • public继承:基类中的公有成员和保护成员在派生类中仍然是公有的和保护的。
  • protected继承:基类中的公有成员和保护成员在派生类中都变成保护的。
  • private继承:基类中的公有成员和保护成员在派生类中都变成私有的。

8. 其余内容

推荐文章:【C++核心】一文理解C++面向对象(超级详细!)(作者:数据知道)


总结

本来学的C++没有学到面向对象编程这块,应为主要用来刷算法题,但由于最近一个项目学习需要到此方面知识,故来学习一下。

相关文章:

C++面向对象编程学习

C面向对象编程学习 前言一、C面向对象编程二、知识点学习1. 定义一个类1.1 使用struct定义1.2 使用class定义1.3 struct和class的区别 2. 类的定义方式2.1 单文件定义&#xff08;Inline Definition&#xff09;2.2 分离定义&#xff08;Separate Definition&#xff09;2.3 头…...

云轴科技ZStack亮相迪拜GITEX大会,与阿里云再次携手深化海外合作

10月14至18日&#xff0c;全球顶尖科技盛会GITEX GLOBAL 2024在迪拜拉开帷幕&#xff0c;云轴科技ZStack携全系云计算解决方案与全新AIOS智塔平台参展&#xff0c;向全球观众展示智算时代下的新一代智算化算力平台。 GITEX GLOBAL 2024是当今世界上最具前瞻性兼包容性的大型科技…...

SQL Server 当前日期及其未来三天的日期

当前日期及其未来三天的日期&#xff0c;并分别以 YYYY-MM-DD 和 yyyyMMdd 的格式展示 1、当前日期及其未来三天的日期&#xff0c;以 YYYY-MM-DD的格式展示 WITH CurrentDate AS (SELECT GETDATE() AS 当前日期 ) -- 使用 CONVERT 函数 SELECTCONVERT(VARCHAR(10), 当前日期,…...

QUIC(Quick UDP Internet Connections)与 RTMP(Real Time Messaging Protocol)

QUIC&#xff08;Quick UDP Internet Connections&#xff09;和 RTMP&#xff08;Real Time Messaging Protocol&#xff09;是两种不同的网络传输协议&#xff0c;它们在一些方面有不同的特点和应用场景。 QUIC 协议 特点 基于 UDP&#xff1a;QUIC 建立在 UDP 之上&#xff…...

双十一送你一份购物攻略,绿联NAS DXP2800评测

一年一度双十一&#xff0c;今年双十一来得特别早&#xff0c;所以最近已经看到不少人在讨论双十一买了啥&#xff0c;NAS的讨论度也挺高的。正好&#xff0c;是我比较懂的领域。作为一位资深的数码爱好者&#xff0c;同时也是绿联DH2600DXP2800双持用户&#xff0c;可以说我是…...

基于vue框架的的高校设备信息管理系统的设计与实现tx6d7(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;设备管理员,设备维护员,设备类别,设备,设备入库,设备分发,设备调拨,定期维护,维护任务,设备运行记录 开题报告内容 基于Vue框架的高校设备信息管理系统的设计与实现开题报告 一、项目背景及意义 随着高校教育事业的蓬勃发展&#xff…...

springboot3.x使用@NacosValue无法获取配置信息问题解决

一、问题描述 springboot从2.x升级到3.x后&#xff0c;nacos的依赖包需要改成Spring Cloud的依赖包才能继续使用。升级好以后&#xff0c;首先&#xff0c;确定我的项目是能够连上nacos并且加载到配置信息的&#xff0c;因为数据库等信息都是从nacos加载过来&#xff0c;能够正…...

sql获取时间差

MySQL SELECT TIMESTAMPDIFF(HOUR, 2023-10-01 12:00:00, 2023-10-02 15:30:00) AS hours_difference; PostgreSQL //EXTRACT(EPOCH FROM (2023-10-02 15:30:00::timestamp - 2023-10-01 12:00:00::timestamp)) // 获取的是两个时间相差的秒数&#xff0c;在此基础上除3600获…...

【深入理解Python中的闭包】如何有效使用嵌套函数和状态捕获!

深入理解Python中的闭包&#xff1a;如何有效使用嵌套函数和状态捕获 Python 作为一种动态的编程语言&#xff0c;允许我们用多种方式来设计和构建功能&#xff0c;其中之一就是 闭包&#xff08;Closure&#xff09;。闭包是一种强大的特性&#xff0c;可以帮助我们捕获和保持…...

npm配置阿里镜像库教程

为了配置npm使用阿里镜像库&#xff0c;可以按照以下步骤进行操作。这些步骤将帮助你加快包的下载速度&#xff0c;特别是在中国地区&#xff0c;因为阿里镜像库通常比官方npm仓库响应更快。 1. 配置全局镜像 可以通过运行以下命令来将npm的全局镜像配置为阿里镜像&#xff1…...

Apache JMeter压力测试工具使用

JMeter是Apache组织开发的基于Java的压力测试工具&#xff0c;用于对软件做压力测试。 01 软件下载 下载地址: https://jmeter.apache.org/download_jmeter.cgi 最新版本5.6.2 用浏览器下载发现慢得很&#xff0c;用迅雷下载非常快哟。 02 测试使用 在使用前需要先安装jd…...

前端零基础入门到上班:【Day4】HTML 多媒体与表单深度教程

HTML 多媒体与表单深度教程 **1. HTML 多媒体基础&#xff1a;深入理解 <video> 和 <audio> 标签****1.1 <video> 标签&#xff1a;详细剖析与用法****1.1.1 基础结构与属性详解****1.1.2 视频格式的兼容性与示例****1.1.3 视频控制的实际应用** **1.2 <a…...

原创作品——银行软件产品界面设计

蓝蓝设计团队服务金融类应用界面设计&#xff0c;以沉稳的色调和简洁的线条营造出专业可靠的氛围。特点在于融入了创新的元素增添界面的活力与现代感。细节处理上&#xff0c;注意数据的视觉呈现效果&#xff0c;采用定制化的图表和清晰的排版&#xff0c;确保用户能够快速理解…...

若依RuoYi-Vue 定时任务 速学

1.若依定时任务模块&#xff08;ruoyi-quartz&#xff09; 那么从一个简单的入门示例开始&#xff0c;掌握定时任务的使用吧&#xff01; 2. 入门示例&#xff08;学会制作一个简单定时任务&#xff09; 首先打开定时任务模块中的task包&#xff0c;这里已经有一个已经写好的R…...

【pytest学习】pytest.main()

基本用法## pytest.main()函数是用于启动测试运行的入口点。它可以在命令行中直接使用&#xff0c;也可以在脚本中以编程方式调用。 以下是一个简单的示例&#xff1a; import pytest if __name__"__main__":pytest.main()执行当前目录下的所有测试文件 使用pytes…...

设计模式: Pimpl(Pointer to Implementation)

这种设计模式通常被称为 Pimpl&#xff08;Pointer to Implementation&#xff09;惯用法&#xff0c;有时也被称为 Cheshire Cat 惯用法。它主要用于隐藏实现细节和减少编译依赖。 例子&#xff1a; DatabaseConnection.h #ifndef DATABASE_CONNECTION_H #define DATABASE_…...

android开发中文网站 android developer

Android 平台 | Platform | Android Developers 在此做个记录...

实习冲刺Day1

算法题 20. 有效的括号 - 力扣&#xff08;LeetCode&#xff09; 这个题我们采用stack栈的方式来进行相应的括号匹配 情况有以下几种 当字符串s中只有一个字符的时候&#xff0c;那这个时候字符串一定是不匹配的所以直接返回false当字符串为发生标准匹配的时候&#xff0c;…...

安全见闻(5)——开阔眼界,不做井底之蛙

安全见闻五&#xff1a;人工智能 内容预览 ≧∀≦ゞ 安全见闻五&#xff1a;人工智能声明导语一、人工智能基础机器学习基础机器学习的典型工作流程1. 数据收集2. 数据预处理3. 模型选择与训练4. 模型评估与优化5. 模型应用 深度学习基础深度学习基本原理1. 神经网络基础2. 多层…...

Navicat 安装

Navicat 安装步骤...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

Vue 模板语句的数据来源

&#x1f9e9; Vue 模板语句的数据来源&#xff1a;全方位解析 Vue 模板&#xff08;<template> 部分&#xff09;中的表达式、指令绑定&#xff08;如 v-bind, v-on&#xff09;和插值&#xff08;{{ }}&#xff09;都在一个特定的作用域内求值。这个作用域由当前 组件…...

git: early EOF

macOS报错&#xff1a; Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...

十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建

【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...

Python实现简单音频数据压缩与解压算法

Python实现简单音频数据压缩与解压算法 引言 在音频数据处理中&#xff0c;压缩算法是降低存储成本和传输效率的关键技术。Python作为一门灵活且功能强大的编程语言&#xff0c;提供了丰富的库和工具来实现音频数据的压缩与解压。本文将通过一个简单的音频数据压缩与解压算法…...

Linux安全加固:从攻防视角构建系统免疫

Linux安全加固:从攻防视角构建系统免疫 构建坚不可摧的数字堡垒 引言:攻防对抗的新纪元 在日益复杂的网络威胁环境中,Linux系统安全已从被动防御转向主动免疫。2023年全球网络安全报告显示,高级持续性威胁(APT)攻击同比增长65%,平均入侵停留时间缩短至48小时。本章将从…...