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

【C++深度探索】继承机制详解(一)

hello hello~ ,这里是大耳朵土土垚~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹
在这里插入图片描述

💥个人主页:大耳朵土土垚的博客
💥 所属专栏:C++入门至进阶
这里将会不定期更新有关C++的内容,希望大家多多点赞关注收藏💖💖

目录

  • 1.继承的概念
  • 2.继承定义
    • 2.1定义格式
    • 2.2访问限定符
    • 2.3继承方式
  • 3.基类和派生类对象赋值转换
  • 4.继承中的重定义(隐藏)
  • 5.派生类的默认成员函数
    • ✨构造函数
    • ✨拷贝构造
    • ✨赋值运算符重载
    • ✨析构函数
  • 6.结语

1.继承的概念

继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类子类。继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用。

2.继承定义

2.1定义格式

下面我们看到Person是父类,也称作基类。Student是子类,也称作派生类。

//基类或父类
class Person
{
public:void Print(){cout << "name:" << _name << endl;cout << "age:" << _age << endl;}
protected:string _name = "peter";// 姓名int _age = 18;  //年龄
};//派生类或子类
class Student : public Person
{
protected:int _stuid; // 学号int _major;	//专业
};

在这里插入图片描述

2.2访问限定符

C++类的访问限定符用于控制类的成员(包括成员变量和成员函数)在类的外部的可访问性。C++中有以下三种访问限定符:

  • public: 公共访问限定符,任何地方都可以访问公共成员。可以在类的外部使用对象名和成员名直接访问公共成员。

  • private: 私有访问限定符,只有类内部的其他成员函数可以访问私有成员。类的外部无法直接访问私有成员,但可以通过公共成员函数间接访问私有成员。

  • protected: 保护访问限定符,只有类内部的其他成员函数和派生类的成员函数可以访问保护成员。类的外部无法直接访问保护成员,但可以通过公共成员函数或派生类的成员函数间接访问保护成员。

需要注意的是,访问限定符只在类的内部起作用,在类的外部没有直接的影响。同时,访问限定符可以用于类的成员变量和成员函数的声明中,默认情况下,成员变量和成员函数的访问限定符是private。

2.3继承方式

在这里插入图片描述
C++类的继承方式有以下几种:

  • 公有继承(public inheritance):使用关键字"public"表示的继承方式。在公有继承中,基类的公有成员和保护成员都可以在派生类中访问,私有成员不能在派生类中直接访问。
class Base {
public:// 公有成员
protected:// 保护成员
private:// 私有成员
};class Derived : public Base {// 公有继承
};
  • 保护继承(protected inheritance):使用关键字"protected"表示的继承方式。在保护继承中,基类的公有成员和保护成员在派生类中都变为保护成员私有成员不能在派生类中直接访问。
class Base {
public:// 公有成员
protected:// 保护成员
private:// 私有成员
};class Derived : protected Base {// 保护继承
};
  • 私有继承(private inheritance):使用关键字"private"表示的继承方式。在私有继承中,基类的公有成员和保护成员在派生类中都变为私有成员,私有成员不能在派生类中直接访问。
class Base {
public:// 公有成员
protected:// 保护成员
private:// 私有成员
};class Derived : private Base {// 私有继承
};

总结如下:

类成员/继承方式public继承protected继承private继承
基类的public成员派生类的public成员派生类的protected成员派生类的private成员
基类的protected成员派生类的protected成员派生类的protected成员派生类的private成员
基类的private成员在派生类中不可见在派生类中不可见在派生类中不可见

①基类的其他成员在子类的访问方式 == Min(成员在基类的访问限定符,继承方式),public > protected > private

这些继承方式可以根据具体的需求选择合适的方式

②基类private成员在派生类中无论以什么方式继承都是不可见的。这里的不可见是指基类的私有成员还是被继承到了派生类对象中,但是语法上限制派生类对象不管在类里面还是类外面都不能去访问它

例如:

//基类或父类
class Person
{
public:void Print(){cout << "name:" << _name << endl;cout << "age:" << _age << endl;}//保护成员
protected:string _name = "tutu";// 姓名int _age = 20;  //年龄//私有成员
private:string _tele = "123456";};//派生类或子类
class Student : public Person
{
public:void sPrint(){Person::Print();	//可以使用父类的公有成员}
protected:int _stuid; // 学号string _sname = _name;//可以访问父类的保护成员_namestring _stele = _tele; //不可以访问父类的私有成员_tele
};

结果如下:
在这里插入图片描述

上述父类Person中成员有三种访问限定分别是public、protected、private,而子类Student使用public继承父类,那么对于父类的公有成员在子类中的访问方式还是public,protected成员访问方式选择继承方式public和protected中较小的protected,同理父类的private成员继承到子类中也是选择private方式,在子类中不可访问

对于私有成员也是被继承到子类中,只是不可访问:

在这里插入图片描述

③基类private成员在派生类中是不能被访问,如果基类成员不想在类外直接被访问,但需要在派生类中能访问,就定义为protected。可以看出保护成员限定符是因继承才出现的。

④ 使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public,不过最好显示的写出继承方式。

⑤在实际运用中一般使用都是public继承,几乎很少使用protetced/private继承,也不提倡使用protetced/private继承,因为protetced/private继承下来的成员都只能在派生类的类里面使用,实际中扩展维护性不强。

3.基类和派生类对象赋值转换

  • 派生类对象可以赋值给基类的对象 / 基类的指针 / 基类的引用。这里有个形象的说法叫切片或者切割。寓意把派生类中父类那部分切来赋值过去。

如下图所示:

在这里插入图片描述

  • 基类对象不能赋值给派生类对象

例如下面代码:

//父类
class Person
{
protected:string _name; // 姓名string _sex;  //性别int _age; // 年龄
};
//子类
class Student : public Person
{
public:int _No; // 学号
};
void Test()
{Student sobj;// 1.子类对象可以赋值给父类对象/指针/引用Person pobj = sobj;Person* pp = &sobj;Person& rp = sobj;//2.基类对象不能赋值给派生类对象sobj = pobj;//error
}

在这里插入图片描述

4.继承中的重定义(隐藏)

  • 在继承体系中基类和派生类都有独立的作用域。
  • 子类和父类中有同名成员,子类成员将屏蔽对父类同名成员的直接访问,这种情况叫隐藏,也叫重定义。

当一个类继承另一个类时,它可以重定义继承的成员函数或者成员变量。
需要注意的是如果是成员函数的隐藏,只需要函数名相同就构成隐藏。

  • 如果要访问被隐藏的父类的同名成员,可以在子类成员函数中,使用 父类::父类成员来显示访问

注意在实际中在继承体系里面最好不要定义同名的成员。

例如:

// Student的_num和Person的_num构成隐藏关系,可以看出这样代码虽然能跑,但是非常容易混淆
//父类
class Person
{
protected:string _name = "胡土土"; // 姓名int _num = 1234; // 身份证号
};//子类
class Student : public Person
{
public:void Print(){cout << " 姓名:" << _name << endl;cout << " 身份证号:" << Person::_num << endl;cout << " 学号:" << _num << endl;}
protected:int _num = 999; // 学号,与父类的_num重名构成隐藏
};void Test()
{Student s1;s1.Print();
};

结果如下:

在这里插入图片描述

我们发现当子类与父类有隐藏关系时,对于同名变量_num的调用,除非显示使用Person::_num 调用的是父类的成员变量,其他情况_num表示的都得子类中定义的变量,这是因为它们有不同的作用域,在子类中调用变量都是先从子类这个作用域中寻找。

再看下面的例子:

class A
{
public:void fun(){cout << "func()" << endl;}
};
class B : public A
{
public:void fun(int i){A::fun();cout << "func(int i)->" << i << endl;}
};void Test()
{B b;b.fun(10);
}

这里 B中的fun和A中的fun不是构成重载,因为不是在同一作用域
B中的fun和A中的fun构成隐藏,成员函数满足函数名相同就构成隐藏。

结果如下:

在这里插入图片描述
如果Test函数中:

void Test()
{B b;b.fun();//这里没有给参数
}

结果如下:

在这里插入图片描述

使用对象b调用fun()没有给参数,这样编译是不通过的,因为这样调用是调用的类B中的成员函数fun是需要传参的,如果要调用基类中的fun函数就必须显示调用,代码如下:

void Test()
{B b;b.A::fun();//显示调用A中的fun函数
}

结果如下:
在这里插入图片描述

5.派生类的默认成员函数

在这里插入图片描述

6个默认成员函数,“默认”的意思就是指我们不写,编译器会变我们自动生成一个,那么在派生类中,(先不考虑取地址重载)这几个成员函数是如何生成的呢?

例如如下父类:

//有如下Person父类
class Person
{
public:Person(const char* name = "tutu"): _name(name){cout << "Person()" << endl;}Person(const Person& p): _name(p._name){cout << "Person(const Person& p)" << endl;}Person& operator=(const Person& p){cout << "Person operator=(const Person& p)" << endl;if (this != &p)_name = p._name;return *this;}~Person(){cout << "~Person()" << endl;}
protected:string _name; // 姓名
};

✨构造函数

  • 派生类的构造函数必须调用基类的默认构造函数初始化基类的那一部分成员。如果基类没有默认的构造函数,则必须在派生类构造函数的初始化列表阶段显示调用基类的构造函数。
//基于上面Person的派生类Student
class Student : public Person
{
protected:int _num; //学号
};
int main()
{Student s;return 0;
}

结果如下:
在这里插入图片描述

在这里插入图片描述

我们发现对于父类中的成员它会自动调用父类Person的默认构造函数与析构函数

  • 如果父类Person没有默认构造函数,那么我们就需要在初始化列表里显示调用父类的构造函数
    例如:
    在这里插入图片描述

当我们将基类的默认构造函数中的缺省值"tutu",去掉,它就不再是默认构造函数,那么在创建子类Student对象时就不会自动调用默认构造函数,会保错,那么这时我们就需要在初始化列表里显示调用

代码如下:

class Student : public Person
{
public:Student(const char* name, int num):Person(name)	//显示调用父类构造函数, _num(num){}	
protected:int _num; //学号
};int main()
{Student s("tutu", 111);;return 0;
}

结果如下:
在这里插入图片描述

还有一种显示调用情况:

在这里插入图片描述

这种情况是不可取的,这是因为规定在初始化列表中是不可以使用父类的成员的

✨拷贝构造

  • 派生类的拷贝构造函数必须调用基类的拷贝构造完成基类的拷贝初始化。

默认生成拷贝构造一般情况下够用,只有当子类成员涉及深拷贝时就必须自己实现拷贝构造

这里也可以自己显示实现一下拷贝构造:

class Student : public Person
{
public://构造函数Student(const char* name, int num):Person(name)	//显示调用父类构造函数, _num(num){}	//拷贝构造Student(const Student& st):Person(st)	//利用前面学习的基类与派生类的赋值转换,_num(st._num){}
protected:int _num; //学号
};

注意这里Person(st)中调用Person中的拷贝构造实现赋值兼容

✨赋值运算符重载

  • 派生类的operator=必须要调用基类的operator=完成基类的复制。

✨析构函数

  • 派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员。因为这样才能保证派生类对象先清理派生类成员再清理基类成员的顺序。

如果自己显示写析构函数:

//析构函数
~Student()
{~Person();//这样写是错误的
}

因为多态的原因,析构函数的名字会被统一处理为destructor(),所以这里调用会构成隐藏,会循环调用,所以要指定作用域:

//析构函数
~Student()
{Person::~Person();cout << "~Student()" << endl;
}

但是我们发现Person的析构函数居然调用了两次:

在这里插入图片描述

这是因为析构函数具有特殊性,在子类析构函数调用完之后会自动调用父类的析构函数,所以即便是自己显示实现了子类的析构函数也不需要自己主动调用父类的析构函数

所以不需要自己主动调用父类的析构函数,否则会报错

其核心原因在于初始化时先构造父类再构造子类,而析构时先析构子类再析构父类,因为子类析构时是可能用到父类成员的,先父后子可能会出错

所以为了保证先析构子类再析构父类,编译器会在析构了子类后自动调用父类的析构函数

总结如下:

默认成员函数\子类成员内置成员自定义成员子类中的父类成员(整体)
默认生成的构造不做处理调用自定义类型的默认构造调用父类的默认构造
默认生成的拷贝构造值拷贝调用自定义类型的拷贝构造调用父类的拷贝构造
默认生成的赋值重载直接赋值调用自定义类型的赋值重载调用父类的赋值重载
默认生成的析构函数不做处理调用自定义类型的析构函数自动调用父类的析构函数

对于构造和析构:
派生类对象初始化先调用基类构造再调派生类构造。
派生类对象析构清理先调用派生类析构再调基类的析构

6.结语

继承可以分为公有继承(public inheritance)、保护继承(protected inheritance)和私有继承(private inheritance)。继承在C++中的应用非常广泛,可以用于构建复杂的类层次结构,提供代码的复用性和灵活性。但是,在使用继承时也需要注意避免多层次的继承导致的类关系复杂性增加,以及合理设计基类和派生类之间的关系。以上就是今天的所以内容啦~ 完结撒花~ 🥳🎉🎉

相关文章:

【C++深度探索】继承机制详解(一)

hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#xff1a;大耳朵土土垚的博客 &#x1…...

力扣第218题“天际线问题”

在本篇文章中&#xff0c;我们将详细解读力扣第218题“天际线问题”。通过学习本篇文章&#xff0c;读者将掌握如何使用扫描线算法和堆来解决这一问题&#xff0c;并了解相关的复杂度分析和模拟面试问答。每种方法都将配以详细的解释&#xff0c;以便于理解。 问题描述 力扣第…...

帝国cms未审核文章可视化预览效果

有时候为了让编辑更加清楚的看到别人审核之后的效果&#xff0c;同时文章有需要下一级审核才能在前端展示出来&#xff0c;今天就来展示一个未审核文章预览审核后的效果 这次给某出版社开发的时候&#xff0c;他们需要实现编辑能够预览自己发布之后的审核效果&#xff0c;所以就…...

医院管理系统带万字文档医院预约挂号管理系统基于spingboot和vue的前后端分离java项目java课程设计java毕业设计

文章目录 仓库管理系统一、项目演示二、项目介绍三、万字项目文档四、部分功能截图五、部分代码展示六、底部获取项目源码带万字文档&#xff08;9.9&#xffe5;带走&#xff09; 仓库管理系统 一、项目演示 医院管理系统 二、项目介绍 基于springbootvue的前后端分离医院管…...

爬虫技术在物联网数据采集中的应用

爬虫技术在物联网数据采集中的应用案例主要包括以下几个方面&#xff1a; 电商平台数据采集&#xff1a;例如&#xff0c;使用Python编写的网络爬虫可以用于爬取京东网页相关数据&#xff0c;如品牌、标题、价格、店铺等&#xff0c;并进行数据处理及可视化展示。这种方法不仅可…...

spring boot初始化的几个总结

spring intializr File->New->Project 注意&#xff1a;Spring Initializer中 Java版本选择模块已经不支持1.8了。 Spring Boot 3.x要求 Java最低版本为17&#xff0c; 最新的SpringBoot版本已经要求Java22了 所以&#xff0c;你可以升级Java版本&#xff0c;使用Spri…...

springcloud第4季 seata报could not find any implementation for class

一 问题说明 1.1 描述 在使用seata2.0alibaba-cloud 2022.0.0.0-RC2nacos 2.2.3 模拟下订单分布式事务场景&#xff0c;出现如下问题&#xff1a;java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0 查看服务端&#xff1a;java.util.ServiceCo…...

IT之家最新科技热点

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…...

对象实例化过程

目录 一、Java对象实例化在JVM中的过程&#xff1a; 类加载与初始化 分配内存 初始化对象内存 设置对象头 执行初始化方法 构造方法执行 二、对象的创建过程 一、Java对象实例化在JVM中的过程&#xff1a; 类加载与初始化&#xff1a; 当JVM需要实例化一个对象时&#xff0c;它…...

常见漏洞之XSS

一、XSS简介 XSS&#xff08;Cross-Site Scripting&#xff0c;跨站脚本攻击&#xff09;是一种常见的网络攻击方式&#xff0c;通过在网页中注入恶意脚本&#xff0c;当其他用户浏览这些网页时&#xff0c;这些嵌入的恶意脚本会在其浏览器上执行&#xff0c;从而进行各种恶意…...

Python变量的命名规则与赋值方式

第二章&#xff1a;Python 基础语法 第一节&#xff1a;变量的命名规则与赋值方式 2.1.1 引言 在编程中&#xff0c;变量是存储数据的基本单元。变量的命名和赋值是编程语言中表达和操作数据的基础。了解和遵循变量命名规则对于编写清晰、可维护的代码至关重要。 2.1.2 变量…...

昇思25天学习打卡营第7天|网络构建

昇思25天学习打卡营第7天|网络构建 前言函数式自动微分函数与计算图微分函数与梯度计算Stop GradientAuxiliary data神经网络梯度计算 个人任务打卡&#xff08;读者请忽略&#xff09;个人理解与总结 前言 非常感谢华为昇思大模型平台和CSDN邀请体验昇思大模型&#xff01;从今…...

扩展阅读:什么是中断

如果用一句话概括操作系统的原理,那就是:整个操作系统就是一个中断驱动的死循环,用最简单的代码解释如下: while(true){doNothing(); } 其他所有事情都是由操作系统提前注册的中断机制和其对应的中断处理函数完成的。我们点击一下鼠标,敲击一下键盘,执行一个程序,…...

git 命令学习之branch 和 tag 操作

引言 在项目一个迭代过程结束之时&#xff0c;或是一个版本发布之后&#xff0c;我们要进行 新版本的开发&#xff0c;这时就需要对原来的项目代码进行封存&#xff0c;以及新项目代码的开始&#xff0c;这时就需要用到 branch 和 tag 操作。下面简单说说对这两个操作的理解。…...

如何理解 IEEE 754 单精度浮点型能表示的最小绝对值、最大绝对值

文章目录 解答最小绝对值最大绝对值总结 细节理解1. 为什么非规格化数的指数偏移量为126&#xff08;而不是127&#xff09;&#xff1f;规格化数与非规格化数非规格化数的指数偏移量非规格化数的尾数非规格化数的值示例 解答 IEEE 754单精度浮点数使用32位来表示一个数值&…...

LeetCode 算法:二叉树的右视图 c++

原题链接&#x1f517;&#xff1a;二叉树的右视图 难度&#xff1a;中等⭐️⭐️ 题目 给定一个二叉树的 根节点 root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 示例 1: 输入: [1,2,3,null,5,null,4…...

Java 并发编程常见问题

1、线程状态它们之间是如何扭转的&#xff1f; 1、谈谈对于多线程的理解&#xff1f; 1、对于多核CPU&#xff0c;多线程可以提升CPU的利用率&#xff1b; 2、对于多IO操作的程序&#xff0c;多线程可以提升系统的整体性能及吞吐量&#xff1b; 3、使用多线程在一些场景下可…...

网络基础:静态路由

静态路由是一种由网络管理员手动配置的路由方式&#xff0c;用于在网络设备&#xff08;如路由器或交换机&#xff09;之间传递数据包。与动态路由不同&#xff0c;静态路由不会根据网络状态的变化自动调整。 不同厂商的网络设备在静态路由的配置上有些许差异&#xff1b;下面…...

库存管理系统基于spingboot vue的前后端分离仓库库存管理系统java项目java课程设计java毕业设计

文章目录 库存管理系统一、项目演示二、项目介绍三、部分功能截图四、部分代码展示五、底部获取项目源码&#xff08;9.9&#xffe5;带走&#xff09; 库存管理系统 一、项目演示 库存管理系统 二、项目介绍 基于spingboot和vue前后端分离的库存管理系统 功能模块&#xff…...

【ArcGIS AddIn插件】【可用于全国水旱灾害风险普查】全网最强洪水淹没分析插件-基于8邻域种子搜索算法-有源淹没分析算法

最近有很多GIS小伙伴咨询我关于基于8邻域种子搜索算法的有源淹没分析插件的使用方法及原理&#xff0c;咱们通过这篇文章给大家详细介绍下这款插件的运行机制。 一、插件类型及适用版本 本插件属于ArcGIS AddIn工具条插件&#xff0c;基于ArcGIS Engine10.2.2的开发环境开发的&…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

1688商品列表API与其他数据源的对接思路

将1688商品列表API与其他数据源对接时&#xff0c;需结合业务场景设计数据流转链路&#xff0c;重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点&#xff1a; 一、核心对接场景与目标 商品数据同步 场景&#xff1a;将1688商品信息…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中&#xff0c;理解API&#xff08;应用程序接口&#xff09;和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能&#xff0c;使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

云原生周刊:k0s 成为 CNCF 沙箱项目

开源项目推荐 HAMi HAMi&#xff08;原名 k8s‑vGPU‑scheduler&#xff09;是一款 CNCF Sandbox 级别的开源 K8s 中间件&#xff0c;通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度&#xff0c;为容器提供统一接口&#xff0c;实现细粒度资源配额…...

基于开源AI智能名片链动2 + 1模式S2B2C商城小程序的沉浸式体验营销研究

摘要&#xff1a;在消费市场竞争日益激烈的当下&#xff0c;传统体验营销方式存在诸多局限。本文聚焦开源AI智能名片链动2 1模式S2B2C商城小程序&#xff0c;探讨其在沉浸式体验营销中的应用。通过对比传统品鉴、工厂参观等初级体验方式&#xff0c;分析沉浸式体验的优势与价值…...

高效的后台管理系统——可进行二次开发

随着互联网技术的迅猛发展&#xff0c;企业的数字化管理变得愈加重要。后台管理系统作为数据存储与业务管理的核心&#xff0c;成为了现代企业不可或缺的一部分。今天我们要介绍的是一款名为 若依后台管理框架 的系统&#xff0c;它不仅支持跨平台应用&#xff0c;还能提供丰富…...

Axure零基础跟我学:展开与收回

亲爱的小伙伴,如有帮助请订阅专栏!跟着老师每课一练,系统学习Axure交互设计课程! Axure产品经理精品视频课https://edu.csdn.net/course/detail/40420 课程主题:Axure菜单展开与收回 课程视频:...

智警杯备赛--excel模块

数据透视与图表制作 创建步骤 创建 1.在Excel的插入或者数据标签页下找到数据透视表的按钮 2.将数据放进“请选择单元格区域“中&#xff0c;点击确定 这是最终结果&#xff0c;但是由于环境启不了&#xff0c;这里用的是自己的excel&#xff0c;真实的环境中的excel根据实训…...