【C++】智能指针 学习总结 |std::shared_ptr |std::unique_ptr | std::weak_ptr
文章目录
- 前言
- 一、智能指针介绍
- 二、普通指针和智能指针的比较案例
- 三、std::shared_ptr
- 四、std::unique_ptr
- 五、std::weak_ptr
- 六、std::shared_ptr |std::unique_ptr | std::weak_ptr三大智能指针的区别
前言
参考答案:chatgpt
一、智能指针介绍
智能指针是C++的一种对象,它可以像常规指针那样,用来指向堆上的数据。然而,智能指针的关键优势在于,**当你不再需要在堆上的数据时,它们可以自动删除。**这是通过在智能指针的析构函数中调用delete来实现的,当智能指针的生命周期结束时(例如,它离开了它的作用域),它的析构函数会被自动调用。
C++标准库提供了几种智能指针:
std::auto_ptr:这是C++98标准的一部分,但在C++11中已被弃用,C++17中已被移除。它具有所有权传递语义,意味着复制auto_ptr会改变原有auto_ptr的状态(会失去指向对象的能力)。
std::unique_ptr:这是C++11引入的智能指针,它表现出独占所有权语义,意味着在任何时间,只有一个unique_ptr可以指向给定的对象。当unique_ptr被销毁(例如,离开其作用域)时,它所指向的对象也会被delete掉。
从 C++14 开始,建议使用 std::make_unique 函数来创建 std::unique_ptr,
auto p = std::make_unique<MyClass>();
std::shared_ptr:这也是C++11引入的智能指针,允许多个shared_ptr指向同一个对象。shared_ptr维护了一个引用计数,当最后一个shared_ptr被销毁(离开其作用域)时,它所指向的对象才会被delete掉。
std::weak_ptr:这也是C++11引入的智能指针,它是对shared_ptr的补充和配合。weak_ptr指向一个由shared_ptr管理的对象,但不会增加该对象的引用计数。这主要用于解决shared_ptr的循环引用问题。
后面三个智能指针用的比较多。
使用智能指针可以帮助管理动态内存,避免内存泄漏。然而,虽然智能指针在许多情况下都非常有用,但它们并不能解决所有内存管理问题,例如,它们无法解决循环引用的问题(除非结合使用weak_ptr)。所以,理解并妥善使用智能指针依然非常重要。
#include < memory>,这个头文件在 C++ 中包含了许多关于内存管理的工具,包括智能指针如 std::unique_ptr 和 std::shared_ptr。
回忆一下,什么是内存泄露?
内存泄漏是指程序中已经动态分配的堆内存由于某种原因程序未释放或者无法释放,导致系统内存的浪费,降低系统性能的现象。如果程序持续运行,内存泄漏会导致系统可用内存逐渐下降,最终可能因为没有足够的内存可用而导致系统崩溃。
例如,以下是一个在 C++ 中产生内存泄漏的简单例子:
#include <iostream>int main() {while (true) {int* p = new int[100]; // 分配内存但未释放}return 0;
}
在这个例子中,程序在一个无限循环中不断地分配内存,但从未释放它。因此,它会不断消耗系统内存,最终可能导致系统崩溃。
解决内存泄漏的方法通常涉及找出程序中没有正确释放的内存,然后修改代码以确保内存在使用后被正确释放。在一些现代编程语言中,如 Java、Python、C#、Go 等,提供了垃圾收集机制,能够自动回收不再使用的内存,从而避免内存泄漏。在 C++ 中,使用智能指针(如 std::unique_ptr 或 std::shared_ptr)也可以帮助管理内存并避免内存泄漏。
二、普通指针和智能指针的比较案例
一个原始指针代码如下:
#include <iostream>struct MyClass {MyClass() { std::cout << "MyClass constructed\n"; }~MyClass() { std::cout << "MyClass destroyed\n"; }
};int main() {MyClass* p = new MyClass(); // 创建 MyClass 实例// 必须显式调用 delete 来释放内存delete p;return 0;
}
在上述代码中,你需要手动管理内存。你必须显式调用 delete 来释放 p 所指向的内存。如果你忘记了,那就会导致内存泄漏。
智能指针:
#include <iostream>
#include <memory>struct MyClass {MyClass() { std::cout << "MyClass constructed\n"; }~MyClass() { std::cout << "MyClass destroyed\n"; }
};int main() {std::unique_ptr<MyClass> p(new MyClass()); // 创建 MyClass 实例// 不需要显式调用 delete 来释放内存// 当 p 离开作用域时,它的析构函数会自动被调用,释放内存return 0;
}
std::unique_ptr:这是一个 std::unique_ptr 模板类的实例,其中的 MyClass 是模板参数,指定了这个智能指针可以指向 MyClass 类型的对象。
p:这是我们为智能指针变量取的名字。
new MyClass():这是使用 new 关键字创建一个新的 MyClass 对象的实例,并返回其内存地址。
std::unique_ptr p(new MyClass());:整个这句代码就是创建一个名为 p 的 std::unique_ptr 对象,它将管理我们新创建的 MyClass 对象的内存。
这里的p()括号里是初始化的意思、std::unique_ptr p(new MyClass()); 中的 new MyClass() 是用来初始化 std::unique_ptr 的。这个表达式创建了一个 MyClass 类型的对象,并返回了指向这个新创建对象的指针。然后,这个指针被用来初始化 std::unique_ptr。
最后结果:
接下来介绍那几种关键的智能指针
三、std::shared_ptr
下面给出一种用法:
#include <iostream>
#include <memory>struct MyClass {MyClass() { std::cout << "MyClass constructed\n"; }~MyClass() { std::cout << "MyClass destroyed\n"; }
};void observe(std::shared_ptr<MyClass> p) {std::cout << "Inside observe function: shared_ptr use_count: " << p.use_count() << "\n";
}int main() {// 使用 std::make_shared 创建 shared_ptrstd::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>();std::cout << "After ptr1 creation: shared_ptr use_count: " << ptr1.use_count() << "\n";{// 创建一个新的 shared_ptr,共享 MyClass 对象的所有权std::shared_ptr<MyClass> ptr2 = ptr1;std::cout << "After ptr2 creation: shared_ptr use_count: " << ptr1.use_count() << "\n";observe(ptr2);} // ptr2 离开作用域,MyClass 对象的所有权计数减一std::cout << "After ptr2 destruction: shared_ptr use_count: " << ptr1.use_count() << "\n";// 现在只有 ptr1 拥有 MyClass 对象
} // ptr1 离开作用域,MyClass 对象的所有权计数归零,MyClass 对象被删除
这段代码的主要目标是展示 std::shared_ptr 的用法和行为。std::shared_ptr 是一个智能指针,它允许多个指针共享同一个对象的所有权。
下面是对每一部分的详细解释:
首先定义了一个名为 MyClass 的结构体,它有一个构造函数和一个析构函数。构造函数和析构函数都会在被调用时输出一段信息。
observe 是一个函数,它接受一个 std::shared_ptr 作为参数,并输出该指针的 use_count(),即该指针当前的引用计数(共享所有权的指针数量)。
main 函数是这段代码的主要部分,展示了 std::shared_ptr 的使用:
使用 std::make_shared 创建了一个新的 std::shared_ptr,名为 ptr1,并使其指向一个新的 MyClass 实例。然后输出 ptr1 的 use_count(),此时应为 1,因为只有 ptr1 指向这个 MyClass 实例。
在一个新的作用域内(由 {} 定义),创建了一个新的 std::shared_ptr,名为 ptr2,并使其也指向 ptr1 所指向的 MyClass 实例。然后输出 ptr1 的 use_count(),此时应为 2,因为 ptr1 和 ptr2 都指向这个 MyClass 实例。
在同一作用域内,调用 observe 函数,并将 ptr2 作为参数传入。observe 函数会输出 ptr2 的 use_count(),此时也应为 2。
当这个作用域结束(即到达 }),ptr2 超出其作用域并被销毁。此时 MyClass 实例的引用计数减一。然后输出 ptr1 的 use_count(),此时应为 1,因为只剩下 ptr1 指向这个 MyClass 实例。
当 main 函数结束,ptr1 也超出其作用域并被销毁。此时 MyClass 实例的引用计数再次减一,变为 0,因此 MyClass 实例被删除,并调用其析构函数。
总的来说,这段代码展示了如何使用 std::shared_ptr 来共享一个对象的所有权,并在所有指向该对象的 std::shared_ptr 都被销毁时自动删除该对象。
最后:
四、std::unique_ptr
下面是一个例子:
#include <iostream>
#include <memory>struct MyClass {MyClass() { std::cout << "MyClass constructed\n"; }~MyClass() { std::cout << "MyClass destroyed\n"; }
};void observe(std::unique_ptr<MyClass>& p) {if (p != nullptr) {std::cout << "Inside observe function: unique_ptr is not nullptr\n";} else {std::cout << "Inside observe function: unique_ptr is nullptr\n";}
}int main() {// 使用 std::make_unique 创建 unique_ptrstd::unique_ptr<MyClass> ptr1 = std::make_unique<MyClass>();observe(ptr1);// 通过 std::move 将所有权从 ptr1 转移给 ptr2std::unique_ptr<MyClass> ptr2 = std::move(ptr1);observe(ptr1);observe(ptr2);
} // MyClass 对象被销毁,因为 ptr2 超出其作用域
在这段代码中,首先使用 std::make_unique 创建了一个 std::unique_ptr,名为 ptr1,并使其指向一个新的 MyClass 实例。然后调用 observe 函数来检查 ptr1 是否为 nullptr。
接下来,通过 std::move 将所有权从 ptr1 转移给新的 std::unique_ptr,名为 ptr2。此时 ptr1 变为 nullptr,因为所有权已经转移走了。
再次调用 observe 函数来检查 ptr1 和 ptr2。此时,ptr1 应为 nullptr,而 ptr2 不应为 nullptr。
当 main 函数结束时,ptr2 也超出其作用域并被销毁。此时,MyClass 实例也被删除,并调用其析构函数。这是因为 std::unique_ptr 在超出作用域时会自动删除其所指向的对象。
五、std::weak_ptr
std::weak_ptr 是一个用于解决 std::shared_ptr 循环引用问题的智能指针。std::weak_ptr 对于对象的所有权是无影响的,只是提供了一种访问共享对象的方式,不会增加引用计数。
以下是一个 std::weak_ptr 的使用例子:
#include <iostream>
#include <memory>struct MyClass {MyClass() { std::cout << "MyClass constructed\n"; }~MyClass() { std::cout << "MyClass destroyed\n"; }
};void observe(std::weak_ptr<MyClass> p) {if (auto spt = p.lock()) { // Must be copied into a shared_ptr before usagestd::cout << "Inside observe function: weak_ptr is not expired, shared_ptr use_count: " << spt.use_count() << "\n";} else {std::cout << "Inside observe function: weak_ptr is expired\n";}
}int main() {std::weak_ptr<MyClass> wptr;{// 使用 std::make_shared 创建 shared_ptrstd::shared_ptr<MyClass> ptr = std::make_shared<MyClass>();wptr = ptr;observe(wptr);} // ptr 离开作用域,MyClass 对象被销毁observe(wptr); // wptr 已经过期,因为 MyClass 对象已经被销毁
}
在这段代码中,首先定义了一个 std::weak_ptr,名为 wptr。
然后在一个新的作用域内(由 {} 定义),创建了一个 std::shared_ptr,名为 ptr,并使其指向一个新的 MyClass 实例。然后将 ptr 赋值给 wptr,使 wptr 也指向 ptr 所指向的 MyClass 实例。
接着调用 observe 函数,将 wptr 作为参数传入。在 observe 函数内部,通过调用 std::weak_ptr::lock 来获取一个指向 MyClass 实例的 std::shared_ptr,并输出其 use_count()。
当这个作用域结束(即到达 }),ptr 超出其作用域并被销毁,MyClass 实例的引用计数减一,变为 0,因此 MyClass 实例被删除,并调用其析构函数。
最后,再次调用 observe 函数,将 wptr 作为参数传入。此时 wptr 已经过期,因为 MyClass 实例已经被销毁,因此 std::weak_ptr::lock 会返回一个空的 std::shared_ptr。
六、std::shared_ptr |std::unique_ptr | std::weak_ptr三大智能指针的区别
std::shared_ptr, std::unique_ptr 和 std::weak_ptr 都是 C++11 引入的智能指针,它们的主要目标是提供自动化的内存管理,以避免内存泄漏。然而,它们之间的区别主要在于如何管理内存以及所有权语义:
std::shared_ptr:这是一种引用计数的智能指针。当你将一个对象的指针赋值给一个 std::shared_ptr 时,它就会开始进行引用计数。如果有其他 std::shared_ptr 指向同一对象,引用计数就会增加。当引用计数变为0(即没有 std::shared_ptr 指向该对象时),对象就会被自动删除。
std::unique_ptr:这种智能指针保证了对象的唯一所有权语义。在任何时候,只有一个 std::unique_ptr 可以指向一个对象。当 std::unique_ptr 超出作用域或被重新赋值时,其原来指向的对象就会被自动删除。如果你需要将所有权转移给另一个 std::unique_ptr,你可以使用 std::move。
std::weak_ptr:这是一种特殊的智能指针,主要用来解决 std::shared_ptr 的循环引用问题。std::weak_ptr 本身不对对象的生命周期造成影响,也就是说,拥有一个指向对象的 std::weak_ptr 不会阻止对象被删除。它只是为了提供一种访问已经存在(并且被 std::shared_ptr 管理)的对象的方式,而不会增加引用计数。要使用 std::weak_ptr,你需要先将其升级为 std::shared_ptr,如果此时对象仍然存在,升级操作就会成功。
这些智能指针都是 C++ 标准库的一部分,设计用来自动管理内存,以避免常规指针可能导致的内存泄漏和其他问题。在编写 C++ 程序时,应优先考虑使用这些智能指针,而不是裸指针。
小插曲:
今天用vscode的时候 调试控制台不输出信息了 比如我print你好,他竟然不输出,只输出几个线程的信息,高的很是烦人,后面找到了解决方案:解决方法
相关文章:
【C++】智能指针 学习总结 |std::shared_ptr |std::unique_ptr | std::weak_ptr
文章目录 前言一、智能指针介绍二、普通指针和智能指针的比较案例三、std::shared_ptr四、std::unique_ptr五、std::weak_ptr六、std::shared_ptr |std::unique_ptr | std::weak_ptr三大智能指针的区别 前言 参考答案:chatgpt 一、智能指针介绍 智能指针是C的一种…...
iptables防火墙
文章目录 一.linux防火墙基础1.linux 包过滤防火墙概述1.1netfilter1.2 iptables 2.包过滤的工作层次2.1 通信的五元素和四元素 3.iptables 的表、链结构3.1 规则链3.2 默认包括5种规则链3.3 规则表3.4 默认包括4个规则表 二.数据包过滤的匹配流程1.规则表之间的顺序2.规则链之…...
properties、yaml作为配置文件的特点
说明:在软件开发中,经常需要把一些配置写在文件中,如数据库配置、MyBatis配置等。这样,后续如果数据库参数有改动,就可以避免直接对代码做修改,只要修改配置文件中关于数据库的配置。关于配置文件的选择&am…...
JavaSE-03 【流程控制语句】
文章目录 JavaSE-03 【流程控制语句】第一章 流程控制1.1 流程概述1.2 顺序结构 第二章 判断语句2.1 判断语句---if2.2 判断语句---if...else2.3 判断语句---if...else if ... else 第三章 选择语句3.1 选择语句--switch3.2 case的穿透性 第四章 循环语句4.1 循环概述4.2 循环语…...
笔记本电脑的BIOS是怎么保护安全的?
随着攻防技术的不断演进,像BIOS攻击、高级网络代码攻击等手段层出不穷,“受害者”也不仅限于企业级服务器、存储,很多魔爪也开始伸向了拥有商业机密数据的PC。 BIOS是Basic Input/Output System(基本输入/输出系统)的…...
Xubuntu之将rm删除内容移至回收站(一百七十七)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…...
STM32F407实现1588v2(ptpd)
硬件: STM32F407ZGT6开发板 软件: VSCode arm-none-eabi-gcc openOCD st-link 在github搜到一个在NUCLEO-F429ZI开发板上移植ptpd的example,因为和F407差别很小,所以就打算用这个demo移植到手头的开发板上。因为目前只需要…...
架构师如何找到自己的商业模式
作为一个架构师,必须要在有限的资源下最大化架构活动所带来的商业价值。对于任何一个架构活动而言,架构师的可用资源,包括商业成本、研发成本、时间成本、迁移成本等等,都是非常有限的。但架构活动就是要在这些限制条件之下&#…...
SQLServer2022安装(Windows),已验证
一、SQLServer2022下载 1、官网下载地址 SQL Server 下载 | Microsoft 2、下载安装包 2.1、选择Developer版本,立即下载。 2.2、打开下载文件夹,双击运行SQL2022-SSEI-Dev.exe 尝试运行SQL2022-SSEI-Dev.exe,会收到以下信息:“…...
facenet, dlib人脸识别,人体检测,云数据库mysql,QQ邮箱,手机验证码,语音播报
目录 部分代码展示: 录入部分 识别部分编辑 活体检测部分编辑 同步到云数据库MySQL 其他操作 部分图片展示: 完整代码加ui链接: 涉及到的一些知识点的文章 部分代码展示: 录入部分 识别部分 活体检测部分 同步到云数…...
Spring Boot 面试题——定时任务
目录 1.什么是 cron 表达式?如何使用?2.Scheduled 注解有什么作用?3.介绍一下 spring-boot-starter-quartz。4.在 Spring Boot 中如何实现定时任务?4.1.使用 Schedule 注解4.2.Quartz 框架 1.什么是 cron 表达式?如何使…...
总建面64万平,配3所幼儿园+54班九年制学校,坪山江岭竹元规划
近日,坪山区城市更新和土地整备局发布,关于《坪山区马峦街道江岭竹元片区城市更新单元规划》已通过深圳市城市规划委员会法定图则委员会审批。现予以公告。 项目位于坪山区马峦街道,南邻南坪快速路,北邻比亚迪路,东西两…...
python3 爬虫相关学习7:使用 BeautifulSoup下载网页图片到本地文件夹
目录 1 一个爬图片pic的代码的例子 1.1 学习的原文章 1.2 原始代码的问题总结 问题1 问题2 问题3 其他问题 1.3 原始代码 2 直接在cmd里 python运行报错 和 处理 2.1 运行报错 2.2 报错原因: 没有提前安装这个bs4 模块 2.3 如何提前知道我的python环境…...
windows平台python脚本执行环境搭建笔记
1.python脚本环境下载 这里是原始发布源: https://www.python.org/downloads/release/python-3114/https://www.python.org/downloads/release/python-3114/安装时记得添加进系统path,这样你可以随时调用python环境。 2.扩展模块的安装 step1.找到py…...
MyBatis的动态SQL之OGNL(Object-Graph Navigation Language)表达式以及各种标签的用法
MyBatis的动态SQL 1、if标签的用法2、choose标签的用法3、where标签4、set标签5、trim的用法6、foreach标签7、bind标签 使用过JDBC或者是其他的ORM框架的开发者都知道,在很多操作中都需要去根据具体的条件进行SQL语句的拼接,并且在有些时候一些标点符号…...
基于Java+Springboot+Vue的二次元商城网站设计与实现
博主介绍:✌擅长Java、微信小程序、Python、Android等,专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇🏻 不然下次找不到哟 Java项目精品实战案…...
MyBatis操作数据库实现
说明:MyBatis是作用于三层架构开发,数据访问层(Data Access Object)的框架,用于访问数据库,对数据进行操作。 一、环境搭建 首先,创建一个SpringBoot模块,然后把MyBatis的环境搭建…...
Git GitLab 使用及规范
Git 基本操作 Git安装配置及基本使用 从官网下载安装包,手动完成安装。打开Git Bash命令行工具,执行命令ssh-keygen -t rsa -C Email-Addresss生成一个密钥对。登录到GitLab,点击右上角你的用户头像,点击Edit Profile settings&…...
【SpringCloud——Sentinel】
一、什么是雪崩? 微服务调用链路中的某个服务发生故障,引起整个链路中的所有微服务都不可用,这就是雪崩。 二、解决雪崩问题的常见措施 1、超时处理 设定超时时间,请求超过一定时间没有响应就返回错误信息,不会无休…...
面试专题:计算机网络常见面试点总结
socket、tcp、udp、http 的认识及区别 socket、tcp、udp、http 的认识及区别 一、先来一个讲TCP、UDP和HTTP关系的 1、TCP/IP是个协议组,可分为三个层次:网络层、传输层和应用层。 在网络层有IP协议、ICMP协议、ARP协议、RARP协议和BOOTP协议。 在传…...
PageHelper失效问题
问题出现记录: 修改代码后,出现分页失效问题,原本的代码再设置了 PageHelper.startPage(pageNum, pageSize);后只有一个mysql查询,我在原本的业务查询前,新增了其他的Mysql查询,导致原需要分页的查询失效 …...
Linux常用命令——grep命令
在线Linux命令查询工具 grep 强大的文本搜索工具 补充说明 grep(global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本&…...
学校热水供应系统方案
学校热水供应系统是现代化校园建设的重要组成部分。一套高效、可靠、安全、环保的热水供应系统,不仅能够满足学生、教职工的日常生活需求,也能提高学校形象和竞争力。 在设计学校热水供应系统方案时,需要考虑以下几个方面: 一、热…...
chatgpt赋能python:Python怎么写绝对值
Python怎么写绝对值 在Python编程语言中,有很多常用函数。其中包括求绝对值的函数。在这篇文章中,我们将介绍如何在Python中使用绝对值函数,并提供一些示例。 什么是绝对值函数? 绝对值函数是一个数学中常用的函数,…...
研发工程师玩转Kubernetes——Node亲和性requiredDuringSchedulingIgnoredDuringExecution几种边界实验
在《研发工程师玩转Kubernetes——使用Node特性定向调度Pod》中,我们提到requiredDuringSchedulingIgnoredDuringExecution只有在规则被满足的时候才能执行调度。本节我们将测试几种边界情况,看看Kubernetes的行为。 没有满足的条件 假设我们测试的Nod…...
OpenCV中的图像处理3.9(六)轮廓线特征与属性
目录 3.9 OpenCV中的轮廓线3.9.1 轮廓线:入门目标什么是轮廓线?如何绘制轮廓线?轮廓线逼近法 3.9.2 轮廓线的特征1. 矩2. 轮廓线面积3. 轮廓线周长4. 轮廓逼近5. 凸面体6. 检查凸性7. 边界矩形8. 最小包围圈9. 拟合椭圆10. 拟合直线 3.9.3 轮…...
burpsuite+xray实现联动测试(手动分析和自动化测试同时进行)
目的:安全测试过程中手动分析测试与xray自动化扫描测试结合,这样可以从多层保障安全测试的分析,针对平台业务接口量大的安全测试是十分有用的,可以实现双向测试同时开始。 xray简介 xray 是一款功能强大的安全评估工具ÿ…...
2023年专业连锁行业研究报告
第一章 行业概况 专业连锁行业是指以连锁经营模式运营的公司,其主要业务涵盖零售、餐饮、酒店、医疗、教育等领域。这些公司通过规模化、标准化的经营模式和供应链管理,提供专业化、高质量的产品和服务。专业连锁行业在全球范围内蓬勃发展,并…...
Mysql数据库(六):基本的SELECT语句
基本的SELECT语句 前言一、SELECT...二、SELECT ... FROM三、列的别名四、去除重复行五、空值参与运算六、着重号七、查询常数八、显示表结构九、过滤数据 前言 本博主将用CSDN记录软件开发求学之路上亲身所得与所学的心得与知识,有兴趣的小伙伴可以关注博主&#…...
在CentOS7环境中,实现使用openresty配置文件,达到jwt指定用户userid不能访问的效果
#在CentOS7环境中,实现使用openresty配置文件,达到jwt指定用户userid不能访问的效果。 首先,你需要安装 OpenResty 和 JWT 组件: 安装 OpenResty 参考 OpenResty 的官方安装文档,在终端执行如下命令: $…...
做的好的自驾游网站/友情链接可以随便找链接加吗
前言 🎄:CSDN的小伙伴们大家好,今天跟大家分享一个二叉树的应用案例——二叉排序树。如果这篇文章对你有用,麻烦给我点个小赞以示鼓励吧🎄 🏡:博客主页:空山新雨后的java知识…...
怎么做应援网站/seo流量优化
1、使用uni-swiper-dot 轮播图指示点 地址:插件地址. 2、使用HBuilderX导入组件 3、按照官方文档使用, 4、文档中并没有说自动轮播,添加属性autoplay"true"就可以了。解决如下 <swiper class"swiper-box" change&q…...
wordpress怎么修改字体颜色/最新实时新闻
2019独角兽企业重金招聘Python工程师标准>>> jquery和layui实现后台大量数据驱动 index.html<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>首页</title><meta name"renderer" content&quo…...
转转怎么做钓鱼网站/阳西网站seo
推土机很好,请参阅Jean-Remy的回答.此外,如果变量根据JavaBeans标准具有getter和setter,那么有许多技术可以帮助您,例如: Apache Commons / BeanUtils示例代码(未测试):final Map aProps BeanUtils.describe(a);final Map bProps BeanUtils.describe(b…...
做网站什么主题比较好/北京seo培训机构
浅谈 Linux 内核无线子系统 本文目录 1. 全局概览2. 模块间接口3. 数据路径与管理路径4. 数据包是如何被发送?5. 谈谈管理路径6. 数据包又是如何被接收?7. 总结一下Linux 内核是如何实现无线网络接口呢?数据包是通过怎样的方式被发送和接收呢…...
还有专门给别人做性奴的网站/百度图片查找
1.介绍 一个一个遍历 定义: 提供一种方法,顺序访问一个集合对象中的各个元素,而不暴露该对象的内部表示 适用场景: 访问一个集合对象的内容而无需暴露它的内部表示 为遍历不同的集合结构提供一个统一的接口 优点: …...