8、操作符重载

友元

  • 可以通过friend关键字,把一个全局函数、另一个类的成员函数或者另一个类整体,声明为授权类的友元
  • 友元拥有访问授权类任何非公有成员的特权
  • 友元声明可以出现在授权类的公有、私有或者保护等任何区域不受访问控制限定符的约束
  • 友元不是成员,其作用域并不隶属于授权类,也不拥有授权类类型的this指针。

操作符标记和操作符函数

双目操作符表达式

L#R

成员函数形式:L.operator#(R)

  • 左操作数是调用对象,右操作数是参数对象

全局函数形式:operator#(L,R)

  • 左操作数是第一个参数,右操作数是第二个参数

单目操作符表达式

#O/O#

  • 成员函数形式:O.operator#()
  • 全局函数形式:operator#(O)

三目操作符表达式: F#S#T

三目操作符无法重载

经典双目操作符

运算类双目操作符:+、-、*、/等

  • 左右操作数均可以为非常左值、常左值或右值
  • 表达式的结果为右值
// 运算类双目操作符函数
#include <iostream>
using namespace std;class Human{
public:Human(int age = 0, const char* name="匿名"):m_age(age),m_name(name){// [int m_age = age;]// [string m_name(name);]}void getInfo(){cout << "姓名:" << m_name << ", 年龄:" << m_age << endl;}// 成员形式操作符函数
//  Human operator+(const Human& r) const {
//      return Human(this->m_age+r.m_age, (this->m_name+"+"+r.m_name).c_str());
//  }
private:int m_age;string m_name;friend Human operator+(const Human& l,const Human& r); // 友元声明
};
// 全局形式操作符函数
Human operator+(const Human& l, const Human& r){return Human(l.m_age+r.m_age, (l.m_name+"+"+r.m_name).c_str());
}int main(void){Human a(22,"张飞"), b(20,"赵云");  // 非常左值const Human c(25,"关羽"), d(32,"马超"); // 常左值Human res = a + b; // ==> a.operator+(b)  或 operator+(a,b)res.getInfo();res = c + d; // ==> c.operator+(d)  或 operator+(c,d)res.getInfo();res = Human(45,"黄忠") + Human(35,"刘备"); // ==> Human(45,"黄忠").operator+(Human(35,"刘备")) 或 //     operator+(Human(45,"黄忠"),Human(35,"刘备"))res.getInfo();return 0;
}

赋值类双目操作符:=、+=、-=、*=、/=等

  • 右操作数可以为非常左值、常左值或右值,但左操作数必须为非常左值
  • 表达式结果为左操作数本身(而非副本)
// 赋值类双目操作符函数
#include <iostream>
using namespace std;class Human{
public:Human(int age = 0, const char* name="匿名"):m_age(age),m_name(name){// [int m_age = age;]// [string m_name(name);]}void getInfo(){cout << "姓名:" << m_name << ", 年龄:" << m_age << endl;}// 成员形式操作符函数Human& operator+=(const Human& r){this->m_age = this->m_age + r.m_age;this->m_name = this->m_name + "+" + r.m_name;return *this;}
private:int m_age;string m_name;friend Human operator+(const Human& l,const Human& r); // 友元声明
};全局形式操作符函数
//Human& operator+(Human& l, const Human& r){
//       l->m_age = l->m_age + r.m_age;
//       l->m_name = l->m_name + "+" + r.m_name;
//       return *l;
//}int main(void){Human a(22,"张飞"), b(20,"赵云");  // 非常左值const Human c(25,"关羽"), d(32,"马超"); // 常左值((a+=b)+=c)+=Human(45,"黄忠");a.getInfo();return 0;
}

比较类双目操作符:>、<、==、<=、>=等

  • 左右操作数为非常左值、常左值或右值
  • 表达式结果为 bool
// 比较类双目操作符函数
#include <iostream>
using namespace std;class Human{
public:Human(int age = 0, const char* name="匿名"):m_age(age),m_name(name){// [int m_age = age;]// [string m_name(name);]}void getInfo(){cout << "姓名:" << m_name << ", 年龄:" << m_age << endl;}
//    // 成员形式操作符函数
//    bool operator==(/*const Human* this */ const Human& that)const{
//        return this->m_age==that.m_age && this->m_name==that.m_name;
//    }
//    bool operator!=(/*const Human* this */ const Human& that)const{return this->m_age!=that.m_age || this->m_name!=that.m_name;
//        return !(*this==that);//使用operator==
//    }
private:int m_age;string m_name;friend bool operator==(const Human& l, const Human& r); // 友元声明friend bool operator!=(const Human& l, const Human& r); // 友元声明
};
// 全局形式操作符函数
bool operator==(const Human& l, const Human& r){return l.m_age==r.m_age && l.m_name==r.m_name;
}
bool operator!=(const Human& l, const Human& r){
//      return l.m_age!=r.m_age || l.m_name!=r.m_name;return !(l==r);//使用operator==
}int main(void){Human a(22,"张飞"), b(20,"赵云");  // 非常左值const Human c(25,"关羽"), d(32,"马超"); // 常左值cout << (a == b) << endl; //0 ==> a.operator==(b) 或者 ...cout << (a != b) << endl; //1 ==> a.operator!=(b) 或者 ...cout << (c == d) << endl; //0 ==> c.operator==(d) 或者 ...cout << (c != d) << endl; //1 ==> c.operator!=(d) 或者 ...cout << (Human(45,"黄忠") == Human(35,"刘备")) << endl; //0 ==> Human(45,"黄忠").operator==(Human(35,"刘备")) 或者 ...cout << (Human(45,"黄忠") != Human(35,"刘备")) << endl; //1 ==> Human(45,"黄忠").operator!=(Human(35,"刘备")) 或者 ...return 0;
}

经典单目操作符

运算类单目操作符:-、~、!等

  • 操作数为非常左值、常左值或右值
  • 表达式的结果为右值
// 运算类单目操作符函数
#include <iostream>
using namespace std;class Human{
public:Human(int age = 0, const char* name="匿名"):m_age(age),m_name(name){// [int m_age = age;]// [string m_name(name);]}void getInfo(){cout << "姓名:" << m_name << ", 年龄:" << m_age << endl;}// 成员形式操作符函数Human operator-(/* const Human* this */)const{return Human(-this->m_age,("-"+this->m_name).c_str());}
private:int m_age;string m_name;
//    friend Human operator-(const Human& l); // 友元声明
};//Human operator-(const Human& l){
//    return Human(-l.m_age,("-"+l.m_name).c_str());
//}
int main(void){Human a(22,"张飞"), b(20,"赵云");  // 非常左值const Human c(25,"关羽"), d(32,"马超"); // 常左值Human res = -a; // ==> a.operator-() 或  ...res.getInfo();//姓名:-张飞, 年龄:-22res = -c; // ==> c.operator-() 或  ...res.getInfo();//姓名:-关羽, 年龄:-25res = -Human(45,"黄忠"); // ==> Human(45,"黄忠").operator-() 或 ...res.getInfo();//姓名:-黄忠, 年龄:-45return 0;
}

前自增减类单目操作符: 前++、前–

  • 操作数为非常左值
  • 表达式的结果为操作数本身(而非副本)

后自增减类单目操作符: 后+ +、后–

  • 操作数为非常左值
  • 表达式的结果为右值,且为自增减以前的值
// 自增减类单目操作符函数
#include <iostream>
using namespace std;class Human{
public:Human(int age = 0, const char* name="匿名"):m_age(age),m_name(name){// [int m_age = age;]// [string m_name(name);]}void getInfo(){cout << "姓名:" << m_name << ", 年龄:" << m_age << endl;}//成员形式操作符函数
//    //   前++   ++a
//    Human& operator++(/* Human* this */){
//        this->m_age+=1;   // 直接加1
//        this->m_name+="a";   // 直接加
//        return *this;
//    }后++  a++
//    Human operator++(/* Human* this */int){
//        Human old = *this;   // 备份原来的值
//        this->m_age+=1;  // 直接加1
//        this->m_name+="a";   // 直接加
//        return old;  // 返回原来的值
//    }
private:int m_age;string m_name;friend  Human& operator++(Human&  l); // 友元声明friend  Human operator++(Human&  l,int); // 友元声明
};//   前++   ++aHuman& operator++(Human&  l){l.m_age+=1;   // 直接加1l.m_name+="a";   // 直接加return l;}//    后++  a++Human operator++(Human& l,int){Human old = l;   // 备份原来的值l.m_age+=1;  // 直接加1l.m_name+="a";   // 直接加return old;  // 返回原来的值}int main(void){Human a(22,"张飞"), b(20,"赵云");  // 非常左值const Human c(25,"关羽"), d(32,"马超"); // 常左值//姓名:张飞a, 年龄:23(++a).getInfo(); // a.operator++() 或 ...//姓名:赵云, 年龄:20(/*|...|*/b++).getInfo(); // b.operator++(0) 或 ...//姓名:赵云a, 年龄:21b.getInfo();return 0;
}

其他操作符

输出操作符: <<

  • 左操作数为非常左值形式的输出流(ostream)对象,右操作数为左值或右值
  • 表达式的结果为左操作数本身(而非副本)
  • 左操作数的类型为ostream,若以成员函数形式重载该操作符,就应将其定义为ostream类的成员,该类为标准库提供,无法添加新的成员,因此只能以全局函数形式重载该操作符

ostream& operator< < (ostream& os, const RIGHT& right) { ...}

// 输入/输出流操作符函数
#include <iostream>
using namespace std;class Human{
public:Human(int age = 0, const char* name="匿名"):m_age(age),m_name(name){// [int m_age = age;]// [string m_name(name);]}
/*  void getInfo(){cout << "姓名:" << m_name << ", 年龄:" << m_age << endl;}*/// 成员形式操作符函数
private:int m_age;string m_name;friend ostream& operator<<(ostream& os, const Human& that);friend istream& operator>>(istream& is, Human& that);
};
// 全局形式操作符函数
ostream& operator<<(ostream& os, const Human& that){os << "姓名:" << that.m_name << ", 年龄:" << that.m_age;return os;
}//istream& operator>>(istream& is, Human& that){
//    is >> that.m_name >> that.m_age;
//    return is;
//}int main(void){Human a(22,"张飞");  // 非常左值const Human b(20,"赵云");  // 常左值cout << a << endl; // cout.operator<<(a) 或 operator<<(cout,a)cout << b << endl; // cout.operator<<(b) 或 operator<<(cout,b)cout << Human(45,"黄忠") << endl; // cout.operator<<(Human(45,"黄忠")) 或 operator<<(cout,Human(45,"黄忠"))//    cin >> a; // cin.operator>>(a) 或 operator>>(cin,a)cout << a << endl;return 0;
}

输入操作符: >>

  • 左操作数为非常左值形式的输入流(istream)对象,右操作数为非常左值
  • 表达式的结果为左操作数本身(而非副本)
  • 左操作数的类型为istream,若以成员函数形式重载该操作符,就应将其定义为istream类的成员,该类为标准库提供,无法添加新的成员,因此只能以全局函数形式重载该操作符

istream& operator>> (istream& is, RIGHT& right) { ...}

// 输入/输出流操作符函数
#include <iostream>
using namespace std;class Human{
public:Human(int age = 0, const char* name="匿名"):m_age(age),m_name(name){// [int m_age = age;]// [string m_name(name);]}
/*  void getInfo(){cout << "姓名:" << m_name << ", 年龄:" << m_age << endl;}*/// 成员形式操作符函数
private:int m_age;string m_name;friend ostream& operator<<(ostream& os, const Human& that);friend istream& operator>>(istream& is, Human& that);
};
// 全局形式操作符函数
ostream& operator<<(ostream& os, const Human& that){os << "姓名:" << that.m_name << ", 年龄:" << that.m_age;return os;
}istream& operator>>(istream& is, Human& that){is >> that.m_name >> that.m_age;return is;
}int main(void){Human a(22,"张飞");  // 非常左值cin >> a; // cin.operator>>(a) 或 operator>>(cin,a)cout << a << endl;return 0;
}

下标操作符:[]

  • 一般用于在容器类型中以下标方式获取数据元素
  • 非常容器的元素为非常左值,常容器的元素为常左值

类型转换操作符

若源类型是基本类型,目标类型是类类型,则只能通过类型转换构造函数实现自定义类型转换

class 目标类型{目标类型(const 源类型& src){ ... }
}

若源类型是类类型,目标类型是基本类型,则只能通过类型转换操作符函数 实现自定义类型转换

class 源类型{operator 目标类型(void) const { ...}
}

若源类型和目标类型都是类类型 (而非基本类型) ,则既可以通过类型转换构造函数也可以通过类型转换操作符函数实现自定义类型转换,但不要两者同时使用

若源类型和目标类型都是基本类型,则无法实现自定义类型转换,基本类型间的类型转换规则完全由编译器内置

类型转换构造函数和类型转换操作符函数

// 类型转换构造函数和类型转换操作符函数
#include <iostream>
using namespace std;class Integer{
public:Integer(int i):m_i(i){//【int m_i = i;】cout << "Integer类的类型转换构造函数被调用" << endl;}operator int(/* const Integer* this */)const{cout << "Integer类的类型转换操作符函数被调用" << endl;return this->m_i;}
private:int m_i;
};int main(void){int n = 666;// int --> Integer(基本类型-->类类型)Integer ix = n; // 定义匿名Integer对象,利用匿名Integer对象.Integer(n) --> 触发类型转换构造函数// Integer ix = n.operator Integer() --> int类中没有一个operator Integer(走不通)                // Integer --> int(类类型 --> 基本类型)int m = ix; // 定义匿名int对象,利用匿名int对象.int(ix)-->int类中没有一个形参是Integer类型的构造函数(走不通)// int m = ix.operator int() --> 触发类型转换操作符函数return 0;
}
// 类型转换构造函数和类型转换操作符函数
#include <iostream>
using namespace std;class Dog; // 短式声明/前置声明class Cat{
public:Cat(const char* name):m_name(name){// [string m_name(name);]}void talk() {cout << m_name << ": 喵喵~~~" << endl;}operator Dog(/* const Cat* this */)const; // 声明
private:string m_name;friend class Dog; // 友元声明
};class Dog{
public:Dog(const char* name):m_name(name){// [string m_name=name;]}
/*    Dog(const Cat& that):m_name(that.m_name){ // 类型转换构造(定制了Cat-->Dog的转换规则)//【string m_name = that.m_name;】cout << "Dog类的类型转换构造函数被调用" << endl;}*/void talk() {cout << m_name << ": 汪汪~~~" << endl;}
private:string m_name;
};
Cat::operator Dog(/* const Cat* this */)const{ // 定义cout << "Cat类的类型转换操作符函数被调用" << endl;return Dog(this->m_name.c_str());
}int main( void ) {Cat smallwhite("小白"); Dog bigyellow = smallwhite;  // 定义匿名Dog类对象,利用匿名Dog类对象.Dog(smallwhite)-->触发Dog类的类型转换构造函数// Dog bigyellow = smallwhite.operator Dog() --> 触发Cat类的类型转换操作符函数return 0;
}

操作符重载的局限

不是所有的操作符都能重载,以下操作符不能重载

  • 作用域限定操作符(::)
  • 直接成员访问操作符(.)
  • 条件操作符(?:)
  • 字节长度操作符(sizeof)
  • 类型信息操作符(typeid)

无法重载所有操作数均为基本类型的操作符: 如实现 1+1=3

c++的前++和后++

  1. 在C语言中
    前++: 先加1,再使用 ++a
    后++: 先使用,再加1 a++
  2. 在C++语言中,不管是前++还是后++,都是直接加1(内部原理和C语言并不同)
    但是C++希望用户感觉和C一样

c++的前++和后++的区别

  • 表达式方式区别:i++是先取变量i,再将变量i值+1;而++i是先将变量i值+1,再取变量i。在循环遍历容器变量时,这两种方式的结果都是一样的,但是,本质的效率上有很大的区别,下面介绍另一种效率区别。
  • 效率:两种方式iterator遍历的次数是相同的,但在STL中效率不同,前++返回引用,后++返回一个临时对象,因为iterator是类模板,使用 it++这种形式要返回一个无用的临时对象,而it++是函数重载,所以编译器无法对其进行优化,所以每遍历一个元素,你就创建并销毁了一个无用的临时对象。C++的标准库,还有符合标准C++的教材,除了特殊需要和对内置类型外,基本都是使用++it来进行元素遍历的,不管是源代码还是教材中都是如此。

下面是标准库源码:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/215882.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt + MySQL(简单的增删改查)

Qt编译MySql插件教程 帮助&#xff1a; SQL Programming QSqlDatabase 静态函数 1.drivers()&#xff0c;得到可以使用的数据库驱动名字的集合 [static] QStringList QSqlDatabase::drivers();2.addDatabase()&#xff0c;添加一个数据库实例 [static] QSqlDatabase QSql…

慢SQL诊断

最近经常遇到技术开发跑来问我慢SQL优化相关工作&#xff0c;所以干脆出几篇SQL相关优化技术月报&#xff0c;我这里就以公司mysql一致的5.7版本来说明下。 在企业中慢SQL问题进场会遇到&#xff0c;尤其像我们这种ERP行业。 成熟的公司企业都会有晚上的慢SQL监控和预警机制。…

Logstash输入Kafka输出Es配置

Logstash介绍 Logstash是一个开源的数据收集引擎&#xff0c;具有实时管道功能。它可以从各种数据源中动态地统一和标准化数据&#xff0c;并将其发送到你选择的目的地。Logstash的早期目标主要是用于收集日志&#xff0c;但现在的功能已经远远超出这个范围。任何事件类型都可…

FastAPI之响应模型

前言 响应模型我认为最主要的作用就是在自动化文档的显示时&#xff0c;可以直接给查看文档的小伙伴显示返回的数据格式。对于后端开发的伙伴来说&#xff0c;其编码的实际意义不大&#xff0c;但是为了可以不用再额外的提供文档&#xff0c;我们只需要添加一个 response_mod…

汽车服务行业分析:预计2028年将达到38亿元

在推进加快检验机构建设同时&#xff0c;综合评估检验机构数量、分布和检测能力&#xff0c;探索试点汽车 4S 店开展检验&#xff0c;提供维修、保养、车检一体化服务。汽车服务主要是指围绕汽车展开的一系列服务活动&#xff0c;包括维修、美容、金融等&#xff0c;除具有一般…

springboot3 liquibase SQL执行失败自动回滚,及自动打tag

一&#xff1a; 自动执行回滚&#xff0c; 已执行成功的忽略&#xff0c;新sql执行失败则执行新sql文件中的回滚sql pom.xml <dependency> <groupId>org.liquibase</groupId> <artifactId>liquibase-core</artifactId> <version>4.25.0&…

Appium 并行测试多个设备

一、前置说明 在自动化测试中&#xff0c;经常需要验证多台设备的兼容性&#xff0c;Appium可以用同一套测试运例并行测试多个设备&#xff0c;以达到验证兼容性的目的。 解决思路&#xff1a; 查找已连接的所有设备&#xff1b;为每台设备启动相应的Appium Server&#xff1b…

从手工测试进阶中高级测试?如何突破职业瓶颈...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、手工测试如何进…

物联网安全芯片ACL16 采用 32 位内核,片内集成多种安全密码模块 且低成本、低功耗

ACL16 芯片是研制的一款32 位的安全芯片&#xff0c;专门面向低成本、低功耗的应用领域&#xff0c; 特别针对各类 USB KEY 和安全 SE 等市场提供完善而有竞争力的解决方案。芯片采用 32 位内核&#xff0c;片内集成多种安全密码模块&#xff0c;包括SM1、 SM2、SM3、 SM4 算法…

权威认证!景联文科技入选杭州市2023年第二批省级“专精特新”中小企业认定名单

为深入贯彻党中央国务院和省委省政府培育专精特新的决策部署&#xff0c;10月7日&#xff0c;杭州市经济和信息化委员会公示了2023年杭州“专精特新”企业名单&#xff08;第二批&#xff09;。 根据工业和信息化部《优质中小企业梯度培育管理暂行办法》&#xff08;工信部企业…

【教3妹学编程-算法题】需要添加的硬币的最小数量

3妹&#xff1a;2哥2哥&#xff0c;你有没有看到新闻&#xff0c; 有人中了2.2亿彩票大奖&#xff01; 2哥 : 看到了&#xff0c;2.2亿啊&#xff0c; 一生一世也花不完。 3妹&#xff1a;为啥我就中不了呢&#xff0c;不开心呀不开心。 2哥 : 得了吧&#xff0c;你又不买彩票&…

最强文生图跨模态大模型:Stable Diffusion

文章目录 一、概述二、Stable Diffusion v1 & v22.1 简介2.2 LAION-5B数据集2.3 CLIP条件控制模型2.4 模型训练 三、Stable Diffusion 发展3.1 图形界面3.1.1 Web UI3.1.2 Comfy UI 3.2 微调方法3.1 Lora 3.3 控制模型3.3.1 ControlNet 四、其他文生图模型4.1 DALL-E24.2 I…

Navicat 技术指引 | 适用于 GaussDB 分布式的服务器对象的创建/设计

Navicat Premium&#xff08;16.3.3 Windows版或以上&#xff09;正式支持 GaussDB 分布式数据库。GaussDB分布式模式更适合对系统可用性和数据处理能力要求较高的场景。Navicat 工具不仅提供可视化数据查看和编辑功能&#xff0c;还提供强大的高阶功能&#xff08;如模型、结构…

NestJS的微服务实现

1.1 基本概念 微服务基本概念&#xff1a;微服务就是将一个项目拆分成多个服务。举个简单的例子&#xff1a;将网站的登录功能可以拆分出来做成一个服务。 微服务分为提供者和消费者&#xff0c;如上“登录服务”就是一个服务提供者&#xff0c;“网站服务器”就是一个服务消…

【C++】类与对象(下)

本文目录 1. 再谈构造函数1.1 构造函数体赋值1.2 初始化列表1.3 explicit关键字 2. static成员2.1 概念2.2 特性 3. 友元3.1 友元函数3.2 友元类 4. 内部类5. 匿名对象6. 拷贝对象时的一些编译器优化7. 再次理解类和对象 1. 再谈构造函数 1.1 构造函数体赋值 在创建对象时&am…

jsonpath:使用Python处理JSON数据

使用Python处理JSON数据 25.1 JSON简介 25.1.1 什么是JSON JSON全称为JavaScript Object Notation&#xff0c;一般翻译为JS标记&#xff0c;是一种轻量级的数据交换格式。是基于ECMAScript的一个子集&#xff0c;采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清…

用 C 写一个卷积神经网络

用 C 写一个卷积神经网络 深度学习领域最近发展很快&#xff0c;前一段时间读transformer论文《Attention Is All You Need》时&#xff0c;被一些神经网络和深度学习的概念搞得云里雾里&#xff0c;其实也根本没读懂。发现深度学习和传统的软件开发工程领域的差别挺大&#xf…

智能优化算法应用:基于入侵杂草算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于入侵杂草算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于入侵杂草算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.入侵杂草算法4.实验参数设定5.算法结果6.…

【FPGA】Verilog:BCD 加法器的实现 | BCD 运算 | Single-level 16 bit 超前进位加法器 | 2-level 16-bit 超前进位加法器

0x00 BCD 运算 在 BCD 中,使用4位值作为操作数,但由于只表示 0 到 9 的数字,因此只使用 0000 到 1001 的二进制数,而不使用 1010 到 1111 的二进制数(dont care)。 因此,不能使用常规的 2complement 运算来计算,需要额外的处理:如果 4 位二进制数的运算结果在 1010 …

quickapp_快应用_快应用与h5交互

快应用与h5交互 h5跳转到快应用[1] 判断当前环境是否支持组件跳转快应用[2] h5跳转到快应用(1)deeplink方式进行跳转(推荐)(2)h5点击组件(接收参数存在问题)(3)url配置跳转(官方不推荐) 问题-浏览器问题 web组件h5页面嵌入快应用快应用发送消息到h5页面h5页面接收快应用发送的消…