都说 C++ 没有 GC,RAII: 那么我算个啥?(赠书福利)

*以下内容为本人的学习笔记,如需要转载,请声明原文链接 微信公众号「ENG八戒」http://mp.weixin.qq.com/s/7A9-tGZxf4w_7eZl3OUQ4A

学过 Java、C# 或者其他托管语言(managed languages)的同学,回过头来看 C++ 的时候,第一反应就是 C++ 没有自动垃圾回收器(GC),而不能充分利用的资源被称为垃圾。

那么 C++ 真的不能自动回收垃圾吗?带着这个疑问我们来看看一般 C++ 程序都是怎样回收资源的。

内存在计算机系统中是有限的资源,通常申请内存和释放内存是这样子的,假设有个被调用的函数 function():

void function()
{
    int *p = new int; // 申请内存

    // 资源申请下来了,不玩有个 p 用?
    // do something

    delete p; // 释放内存
}

这段示例代码在 function() 函数开始的时候申请了一块内存,大小对应于 int 类型,然后在函数结束的时候释放它。通常来说,这看起来很OK,没毛病,但是,如果遇到了下面几种情况呢?

  • 程序如果中途有逻辑让它提前退出 function() 函数
  • 发生了异常而没有被捕获到

那么在函数尾部执行释放内存的动作有几率不会被执行,意味着发生也会内存泄漏。像上面这段代码,如果调用的次数不多也不碍事,不过,如果循环调用 function(),这时泄露的内存资源会不断累积,而且一直被浪费掉,期间系统无法再次使用这些被浪费的内存,直到进程被终止,严重的话,会导致系统资源被耗尽,跑着跑着系统都崩溃了。这种 bug 在 C 范式的编程语言中真的很常见。

RAII 是什么

众所周知 C++ 具有面向对象的特性,在初始化类对象的时候,系统会调用类构造函数。如果类对象是存放在栈空间的话,比如声明为局部变量,那么当类对象超出生命周期时,比如退出局部变量的作用域,系统会调用这个对象的类析构函数;如果类对象是存放在堆空间的话,比如通过 new 操作符创建的类对象,那么当类对象被销毁时,比如对对象执行 delete 操作,系统同样会调用类析构函数。

C++ 的这个特性可以用来解决上面提到的资源泄露问题,怎么利用呢?

modern C++ 实践建议优先把资源存放在栈上。如果只是个变量类型,完全可以用局部变量的形式定义声明,这样代码块在退出后系统自动回收栈上的资源。

对上面的函数 function() 修改

void function()
{
    // 声明定义为局部变量,资源存储在栈区
    int data = 0;

    // do something with data

    // 函数退出时,自动释放 data 占用的空间
}

当资源比较占空间时,需要在堆上分配资源,可以通过指针引用它,资源的申请放在类的构造函数里,然后在析构函数里释放。下面举个例子

class Helper
{
private:
    int* data;
public:
    Helper() {
        data = new int; // 在堆上申请内存
    }
    ~Helper() {
        delete data; // 释放堆上申请的内存
    }
    void do_something_with_data() {}
};

void function()
{
    // 声明定义为局部变量,对象存储在栈区
    // 调用 Helper 类构造函数在堆上申请资源
    Helper help;

    // 通过对象 help 调用成员 data
    // 如果 data 是 Helper 私有成员
    // 在类外面必须通过类成员方法调用 data
    help.do_something_with_data();

    // 函数退出时,自动释放 help 对象占用的栈空间
    // 就算发生了异常或者中途退出都会执行这一步
    // help 对象被销毁时,调用 Helper 类析构函数
    // Helper 类析构函数释放已申请的堆上资源
}

利用这种特性的行为被 C++ 发明人称呼为 RAII,英文全称是「resource acquisition is initialization」,中文翻译过来是「资源获取即是初始化」。而我喜欢把它叫做上下文管理,实现资源申请释放的类叫做上下文管理器(context manager)。

经典实践--智能指针

上面的示例代码写起来略显啰嗦,为了推广这种设计核心思路和简化代码编写,在 C++ 11 之后标准库里添加了 unique_ptr。

unique_ptr 属于 Smart Points 中的一种,Smart Points 在国内通常翻译为「智能指针」。智能指针负责管理和释放资源。上面的 function() 函数可以改成这样子

#include <memory>
void function()
{
    // 实例化智能指针对象,输入需要被管理的内存首地址
    // 对象为局部变量,存储在栈区
    std::unique_ptr<int> data(new int);

    // 智能指针对象就像普通指针一样调用
    printf("data=%d\n", *data);

    // 函数退出时,自动释放 data 对象占用的栈空间
    // 就算发生了异常或者中途退出都会执行这一步
    // data 对象被销毁时,同步释放被管理的内存资源
}

可见,用了智能指针后,不需要像之前那样定义类 Helper (上下文管理器)了,代码清爽很多。

不过,上面的示例代码中有个地方需要注意,在实例化智能指针对象时必须传入内存地址,有没有其它更好的方式设置被管理的内存地址?

有的,C++ 14 之后标准库添加了 make_unique,演示一下怎么用

std::unique_ptr<int> data = std::make_unique<int>();

荐书活动

编程的设计思想是一门很有意思的事情,其中有一门前人总结得很到位的学问叫「设计模式」,想深入了解吗?

最近在联合机械工业出版社搞荐书活动,这次参与活动的图书是《深入理解设计模式》,作者是林祥纤。

其中有几本样书,八戒 想送给读者朋友,需要免费领取图书的朋友可以点击文章抬头的原文链接!

图书简介:

本书以作者与虚拟女友(小璐)在生活中遇到的各种问题作为主线,引出设计模式的各种功能、用途,以及解决方法,系统介绍了23种设计模式,根据具体的实例形象化、具体化地进行了代码的编写和详细讲解,让那些本来对设计模式不太了解、一知半解、只有概念的读者,彻底了解和掌握常用的设计模式使用场景及使用方式,并掌握每个设计模式的UML结构和描绘方式。

本书共23章,包括认识设计模式、单例模式、工厂模式、建造者模式、原型模式、适配器模式、装饰器模式、外观模式、桥接模式、组合模式、享元模式、代理模式、策略模式、命令模式、状态模式、模板方法模式、备忘录模式、中介者模式、观察者模式、迭代器模式、责任链模式、访问者模式、解释器模式。

通过以上的知识,让你从模式小白直接升级为模式大神!本书所需源代码,均可通过本书配套下载链接获得。 本书适合编程初学者或希望在面向对象编程上有所提高的开发人员阅读。


本文转载于网络 如有侵权请联系删除

相关文章

  • latex中插入图片[通俗易懂]

    大家好,又见面了,我是你们的朋友全栈君。latex排版之插入图片:在排版图片之前,个人认为不管用不用到,引入下面两个包:\usepackage{graphicx} \usepackage{subfigure}(1)插入单个图片,图片格式为png\begin{figure}[h] \centering \includegraphics[width=4cm,height=5cm]{3} \caption{这是一张图片,名字是3.png.} \end{figure}复制上面代码,第一行中[h]代表图片就在当前位置,有的时候latex排版的时候图片太大,而剩余的空间太小,latex就会自动将图片放在文档中的一个合适的地方,如果不想这样,可以加上[h].\centering图片的位置居中。第三行表示插入图片的长宽,后面的3代表图片的名字,这个我在文件夹中的名字是3.png。第四行表示图题。(2)并排插入两张图片(每张图片有自己的图题),这种方法会使latex中图片的编号顺序向后增加。\begin{figure}[h] \begin{minipage}[t]{0.45\linewidth} \ce

  • Mastodon 对接腾讯云 COS 存储实战

    0x00.前言看到文档活动中心出了COS征文活动,就又来参加了,这次会介绍一下自己在微博客场景下是如何使用COS的0x01.Mastodon参照维基百科Mastodon是一个自由开源的去中心化的分布式微博客社交网络。它的用户界面和操作方式跟推特类似,但整个网络并非由单一机构运作,而是以多个由不同营运者独立运作的服务器以联邦方式交换资料而组成的去中心化社交网络。参照官方描述Mastodonisafree,open-sourcesocialnetworkserverbasedonActivityPubwhereuserscanfollowfriendsanddiscovernewones.OnMastodon,userscanpublishanythingtheywant:links,pictures,text,video.AllMastodonserversareinteroperableasafederatednetwork(usersononeservercanseamlesslycommunicatewithusersfromanotherone,includingnon-Mast

  • 什么是SOCKS5代理?

    什么是代理服务器?SOCKS5与HTTP代理的区别?这类代理会被检测到吗?在今天的这篇文章中,Oxylabs将为您解答以上常见问题。什么是SOCKS代理?SOCKS代表SOCKetSecure,也是一种互联网协议,常用于内容流媒体播放或P2P共享等流量密集型活动。SOCKS通过传输控制协议(TCP)连接,这种连接专门用于通过互联网发送和接收数据包,并确保能通过网络成功传输资源。 使用SOCKS代理时,会代客户端根据TCP协议通过代理服务器路由网络流量。与其他代理一样,SOCKS代理也可以隐藏客户端IP地址,帮助绕过地域限制。与HTTP有所不同,SOCKS无法读取网络数据。它一般用于协助与设有防火墙且限制普通客户端访问的网站进行通信,最重要的是,SOCKS代理可以基于任何网络协议,在无论什么端口上运行。 什么是SOCKS5?SOCKS5是最新版本的SOCKS协议。相比前代版本,SOCKS5支持TCP、UDP连接,更加安全。如果您对SOCKS5有任何疑问或者还想深入了解特定主题,可查看文章了解更多详情!

  • OpenVPN每个客户端为什么占用4个IP?

    背景对于内部系统的访问,我们也是采用了常见openVPN网络隧道方案实现业务远程访问。最近北京疫情有点严重,响应政府号召居家远程上班,openVPN的使用者也随着内部系统增多变得越来越多。最近收到公司有人反馈,openVPN刚开始使用还好好的,现在连接状态也是正常的,怎么就打不开系统了呢?听反馈说,openVPN客户端连接软件也重启了,电脑也重启了,还是打不开,听着很是诡异,于是远程看了一下openVPN客户端的连接日志如下:看到这些的时候,也是相对纳闷的,我自己用的还好好的啊,于是重新进行了一次连接,发现连接正常,系统也能打开。还以为此时解决了,但是又收到一个相同反馈此问题的,于是就不淡定了,去服务端看了一下日志: TueMay1016:11:412022us=8473254C:5E:0C:2C:F3:5A/11.1.1.105:57637MULTI:nofree--ifconfig-pooladdressesareavailable TueMay1016:11:412022us=8473804C:5E:0C:2C:F3:5A/11.1.1.105:57637MULTI:nodyna

  • [浅析] 特定场景下代替优化 if-else 的方案 (二)

    前言很久之前,发了一篇文章:[浅析]特定场景下取代if-else和switch的方案,但是关于使用if-else的场景可不会仅仅是上面文章那么少,还有很多的场景,今天再次写下在开发上有哪些可以代替或者优化if-else的场景。这里强调代替或者优化if-else,是在特定场景下进行的。目的就是为了在特定场景下改善代码,让代码简洁。增加代码的可读性,维护性,复用性。如果if-else使用的场景比较简单,或者代替,优化if-else后会对代码产生不好的影响。就不建议使用别的方案代替或者优化,不能为了不写if-else而不写,不能为了优化而优化。1.范围查询比如抽取中奖的号码区间,中奖的号码区间分别是9-12,14-18,然后需要判断号码是否中奖了,逻辑很简单就实现了letnum1=15 letnum2=13 if((num1>=9&&num1<=12)||(num1>=14&&num1<=18)){ //中奖了 } if((num2>=9&&num2<=12)||(num2>=14&&n

  • 20岁中芯国际2020首份财报:国产芯片的艰难之旅

    20岁的中芯国际,还追得动吗? 最近多家从事半导体行业相关业务的公司都相继发布了Q4财报,中芯国际也是其中之一。 2019年对于半导体行业来说并不是个“幸运年”,不过,四季度相较来说是整个年度中表现较好的一个时期。 中芯国际四季度也向市场交出了一份相对不错的答卷。作为14纳米工艺量产后的首份财报,其可圈可点之处不单单只体现在一点上。 厚积薄发,成效初显 根据中芯国际2月14日发布的四季度财报,本季度的营收达到8.39亿美元,同环比均有增长。同时,由于产能有所提高,毛利同比增长了48.7%,毛利率上升6.8个百分点。 正如财报开头中芯国际的联合CEO赵海军和梁孟松所言,中芯国际的经营状况在转好。结合中芯国际2019年各季度的数据,营收同比分别是-19.5%、-11.2%、-4.0%、6.6%,同比增长趋势明显。 可能对于大多数不从事相关行业的人来说,中芯国际这个名字是初次听说,但实际上中芯国际是内地最大的芯片代工厂,而它也是中国半导体行业中非常具有代表性的一家公司。 中芯国际成立于2000年。中国半导体协会副理事长于燮康去年年末在珠海的演讲提到,中国半导体产业在2000至2008年进入快

  • 上百种预训练中文词向量:Chinese-Word-Vectors

    昨天聊到腾讯AILab的词向量:相似词查询:玩转腾讯AILab中文词向量,今天趁热打铁,推荐Github上的一个中文词向量项目:Chinese-Word-Vectors,Github地址,可点击文末"阅读原文"查看:https://github.com/Embedding/Chinese-Word-Vectors这个项目发布于去年年中,和ACL2018的论文相伴而发:《AnalogicalReasoningonChineseMorphologicalandSemanticRelations》,作者团队来自北京师范大学和中国人民大学。该项目基于百度百科,中文维基百科、人民日报、搜狗新闻、知乎问答、微博等中文语料预训练了上百种中文词向量,Github主页上每个词向量都对应有百度网盘链接,感兴趣的同学可以关注,以下来自Github原文。ChineseWordVectors中文词向量Thisprojectprovides100+ChineseWordVectors(embeddings)trainedwithdifferentrepresentations(denseand

  • leetcode 172 Factorial Trailing Zeroes

    Givenanintegern,returnthenumberoftrailingzeroesinn!.Note:Yoursolutionshouldbeinlogarithmictimecomplexity.解决思路: 决定阶乘末尾零的个数其实是数列中5出现的次数,比如5的阶乘一个零。1024的阶乘末尾到底有几个零呢?http://bbs.csdn.net/topics/380161955 代码如下:inttrailingZeroes(intn) { inttotal=0; while(n>=5) { n=(n-(n%5))/5; total=total+n; } returntotal; }复制python的解决方案:classSolution: #@returnaninteger deftrailingZeroes(self,n): factor,count=5,0 whileTrue: curCount=n//factor ifnotcurCount: break count+=curCount factor*=5 returncount复制

  • Struts2学习---简单的数据校验、访问Web元素 1.简单的数据校验访问Web元素

    1.简单的数据校验在action里面我们已经给出了一个数据校验:publicStringexecute(){ if(user.getUsername().equals("username")&&user.getPassword().equals("password")){ returnSUCCESS; } returnERROR; }复制这里是action的传送门 上面代码大概就是如果用户名为“username”,并且密码为“password”的将返回success指定的页面(由action里面的result的属性name指定),否则返回error指定的页面。这是我们人为的指定错误页面。struts也提供给我们它处理错误的方式:publicStringadd(){ if(name==null||!name.equals("admin")){ this.addFieldError("name","nameiserror"); returnERROR; } returnSUC

  • EasySwoole的入门学习

    大家好,又见面了,我是你们的朋友全栈君。EasySwoole的入门学习官网地址:https://www.easyswoole.com/一、安装easyswoole:(1)建立安装目录:cd/data mkdireasyswoole cdeasyswoole复制(2)使用composer下载easyswoole:composerrequireeasyswoole/easyswoole=3.x复制(3)安装:phpvender/easyswoole/easyswoole/bin/easyswooleinstall复制(4)启动:phpeasyswoolestart复制(5)查看启动情况:netstat-tunlp|grep9501复制可以看到结果:tcp000.0.0.0:95010.0.0.0:*LISTEN4015/EasySwoole复制通过浏览器访问:http://127.0.0.1:9501可以访问到。框架安装完毕。二、编写业务代码:(1)框架根目录下的dev.php是开发环境下的项目配置文件,可以配置redis、mysql等信息。(2)手动建立应用目录,如下:|─App应用目录

  • 大道如青天,协程来通信,Go lang1.18入门精炼教程,由白丁入鸿儒,Go lang通道channel的使用EP14

    众所周知,Golang的作用域相对严格,数据之间的通信往往要依靠参数的传递,但如果想在多个协程任务中间做数据通信,就需要通道(channel)的参与,我们可以把数据封装成一个对象,然后把这个对象的指针传入某个通道变量中,另外一个协程从这个通道中读出变量的指针,并处理其指向的内存对象。 通道的声明与创建 packagemain import"fmt" funcmain(){ varachanint ifa==nil{ fmt.Println("通道是空的,不能使用,需要先创建通道") a=make(chanint) fmt.Printf("数据类型是:%T",a) } } 复制 这里注意,通道声明之后还需要进行创建。 也可以通过海象操作符声明并创建: packagemain import"fmt" funcmain(){ a:=make(chanint) fmt.Printf("数据类型是:%T",a) } 复制 程序返回: 数据类型是:chanint% 复制 如此,一个类型为整形的通道就创建好了。 此外,通道是引用数据类型: package

  • 关闭显示远程桌面mstsc顶部(侧面)连接栏

    在进行mstsc远程桌面连接电脑或者虚拟机的时候,总是会出现一个连接栏。虽然点左边的图钉可以自动隐藏,但是每次鼠标滑到上面的时候,还是会冒出来,这个就有点闹心了。 查了下相关资料,解决了,特写下相关教程; 关闭步骤:在进行远程连接的时候,取消选择显示->全屏显示时显示连接栏(B)。 如果要退出远程连接的话,Ctrl+Alt+Home,在全屏模式下,激活连接栏,然后叉掉就好了。 笔记本可能没有HOME键 HOME键和左方向键共用,打开HOME的方法是FN+HOME 所有笔记本唤醒连接栏的方法就是:Ctrl+Alt+FN+Home   出处:https://www.cnblogs.com/zhupengfei/p/15370815.html 您的资助是我最大的动力!金额随意,欢迎来赏! 付款后有任何问题请给我留言。 如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】按钮。 如果,您希望更容易地发现我的新博客,不妨点击一下绿色通道的【关注我】。(●'◡'●) 如果对你有所帮助,赞助一杯咖啡!打   &

  • JAVA语言编程思想

    在我们所学的语言中,有些是面向过程的,分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。我们所熟悉的C便是典型面向过程的语言。而此外,还有一种是面向对象的,把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。JAVA作为面向对象语言中的代表,有哪些编程思想呢? 可封装 让抽象的事物保护自身的状态,防止非其他事物对其进行错误的状态改变操作。我们抽象完一个事物后,可能在特定的条件下,其本身的状态需要改变,但是这个改变并允许其他的事物来进行,这样的改变只允许这个事物认同的操作域来进行,可以是该事物本身,也可以是它信任的其他事物。这样我们就能对我们抽象完的每个事物进行自身数据的保护 可继承 让抽象出来的事物具有本应该具有的联系。我们能用类来描叙一个抽象的事物,同时能用对象来描叙具体的事物,但是这些事物都是独立的,彼此之间没有应该有的联系,这样的孤立设计并不符合现实逻辑,让事物之间的联系得到描叙,我们就需要继承,例如:发明自行车的人并不是一开始就发明了多人自行车,这些都是从双轮自行车

  • C#数据结构-赫夫曼树

    什么是赫夫曼树? 赫夫曼树(HuffmanTree)是指给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小。哈夫曼树(也称为最优二叉树)是带权路径长度最短的树,权值较大的结点离根较近。 1  publicclassHNode<T> 2{ 3publicHNode() 4{ 5data=default(T); 6weight=0; 7leftNode=null; 8rightNode=null; 9} 10 11publicHNode(Tval) 12{ 13data=val; 14weight=0; 15leftNode=null; 16rightNode=null; 17} 18 19///<summary> 20///权重 21///</summary> 22publicintweight{get;set;} 23 24///<summary> 25///内容 26///</summary> 27publicTdata{get;set;} 28 29///<summary> 30///

  • ORA-00911错误及解决方法

    转载自:http://www.cnblogs.com/zhangronghua/archive/2007/08/29/874484.html 2007年的。   今天在开发中遇到了一个问题,被困扰了好找时间。 事情是这样的, 因为我们现在做的系统数据库是用oracle,而我又喜欢凡是和数据库 有关的语句先在pl/sqldeveloper里面测试好了,再往程序里面写。而今天做的代码里 面涉及到查询库里面现在有没有用户输入的表所对应的同义词。所以我便写了这样的一条语句: string.format(select*fromuser_synonymswhereupper(synonym_name)='{0}' and upper(table_name)='{0}';",     this.txtSourceTableName.Text.ToUpper());谁知在调试的时候走到这个地方就报“ORA-00911:无效字符”的错误。 解决办法: 可是我明明在pl/sqldeveloper里面测试好了的。困惑了好一会,才发现是最

  • 移动端界面设计之尺寸篇

    移动端界面设计之尺寸篇 作者其它设计文章:PS图层样式之高级混合(1)PS图层样式之高级混合(2)手机音乐界面设计分析AE动画设计基础篇移动端界面设计之尺寸篇 作者在写这篇文章时候还没有出iphone6,所以把这一部分的给补上,相关的尺寸请点下面2篇文章查看。 移动端界面设计之尺寸篇(淘宝版) iPhone6&6Plus视觉设计适配说明 h5移动端页面设计学习文档

  • 项目性能优化

    1.cdns托管静态资源; 2.vue操作虚拟dom,不引起回流重绘; 3使用缓存,减少http请求; 4.图片懒加载,路由懒加载; 5.公共方法的封装,公共组件,样式的提取; 6.代码走查,团队风格统一; 7.频繁触发的事件,使用防抖节流技术。  

  • 夜思——生于忧患,死于安乐

    这一周是难度飞升的一周,也是暴露出我短处的一周,同时也让我吃到了数分挂科的苦头。 是时候后该剖析一下自我了。 周一的个人赛着实震惊到我了,KMP,线段树啥的我完全不会,三个小时下来只做了一道题。突然发现原来大家都学这么多了。再看看自己,IDA*还没搞明白,DP更是还没有系统的开始学习,而且这周还要讲数论。 一番天人交战后决定先搞数论,然后我意识到了学好数学分析是多么重要。 这几个算法的证明已经花了我10+小时,虽然很多队友也不会证明,但我一个数学专业的不会这等程度的证明是要谢罪的,因为我们三主科之一就是专门研究证明的。 每晚三个小时砸进去,费力的把进度推进一点点,再回头一看自己做了很多的无用功。又想到明天要收的数学作业还没做,上课又要听不懂,又可能开始新的恶性循环。想想同学们在自习室里写作业,背单词,看看课外书丰富丰富思想;再看看自己在这里舒舒服服地坐了三个半钟头,飞扬浮躁,东西没学到多少,水群冲浪看黄图到是一件不少。 本来是思想激荡,实现梦想的地方;如今却隐隐透露出了堕落的气息。扪心自问: “是放飞理想,还是放飞自我?” 问题出在思想上,当来之不易的好日子成了理所当然,懒惰便开始滋

  • WSL2相关问题

    遇事不决wsl--shutdown

  • 手机视频加手机壳小软件

    ​ 今天小编给大家分享一个和短视频有关,有趣的手机工具软件,非常简单就能给视频添加手机外壳。打开软件,主页面极简清爽,不存在什么花里胡哨的东西,没有任何广告。   1   软件使用       软件以为你打包好,回复20200813即可领取。   通过右下方的调色面板可以对整个视频的框架进行调色设置,点击页面中下方的(1/2)位置可对手机框进行颜色调整。           屏幕的左上角功能选区打开后可以看到“机型列表”选区,里有多种机型框可以选择,大家根据自己的喜好选择就好。         颜色与手机框选择完毕之后,在其基础上添加好素材视频即可(点击手机外壳,选择视频素材),视频处理的时间长短取决视频内容长短,处理完成后会在下方显示存储路径,点击存储路径即可查看视频哦,小编体验感觉非常不错,感兴趣的朋友可以下载看看。         加壳视频效果展示:  https

  • php中使用ajax进行前后端json数据交互

    (最近在学习ajax,所以想自己总结一下在PHP中如何使用ajax技术!) 一、ajax注意点:   1、原理图:(来自韩顺平ajax视频)          2、ajax返回数据类型:       文本,json,xml      (1)文本格式:               (2)xml:          1<?php 2//告诉浏览器返回的是xml类型 3header("Content-Type:text/xml;charset=utf-8"); 4 5 6 7 8?>复制 ViewCode                 前端如何取出:         xmlrequest.responseXml();//返回的是对象       (3)json:       json只是一种文本字符串,他是存储在responseText属性中。 二、实现(通过添加图书案例来实现,由于题目主要是用json来传输,所以我选择json格式传输,但这个案例用json实在是太勉强了):   1、使用javascript来实现:     前端注册界面:      

相关推荐

推荐阅读