C++核心编程:类和对象 笔记
4.类和对象
- C++面向对象的三大特性为:封装,继承,多态
- C++认为万事万物都皆为对象,对象上有其属性和行为
例如:
- 人可以作为对象,属性有姓名、年龄、身高、体重...,行为有走、跑、跳、说话...
- 车可以作为对象,属性有轮胎、方向盘、车灯...,行为有载人、放音乐、开空调...
- 具有相同性质的对象,我们可以对其进行抽象,抽象为类,人属于人类,车属于车类
4.1 封装
4.1.1 封装的意义
- 封装是C++面向对象三大特性之一
- 封装的意义:
- 将属性和行为作为一个整体,表现生活中的事物
- 将属性和行为加以权限控制
封装意义一:在设计类的时候,属性和行为写在一起,表现事物
语法:class 类名{访问权限: 属性 / 行为};
类中的属性和行为 我们统一称为成员
- 属性 -> 成员属性/成员变量
- 行为 -> 成员函数/成员方法
- 示例1:设计一个圆类,求圆的周长
- 类和对象-封装-属性和行为作为整体.cpp
#include <iostream>
using namespace std;
// 圆周率
const double PI = 3.1415926;
// 设计一个圆类,求圆的周长
// 圆求周长的公式 : 2 * PI * 半径
class Circle {// 访问权限// 公共权限
public:// 行为// 获取圆的周长double calculatePerimeter(double radius) {return 2 * PI * radius;}// 属性:半径int m_radius;
};
int main() {// 通过圆类,创建具体的圆(对象)// 实例化(通过一个类 创建一个对象的过程)Circle c1;c1.m_radius = 10;cout<<"圆的周长为 : "<<c1.calculatePerimeter(c1.m_radius)<<""<<endl;return 0;
}
- 示例2:设计学生类
#include <iostream>
using namespace std;
#include <string>
// 设计一个学生类,属性有姓名和学号
// 可以给姓名和学号赋值,可以显示学生的姓名和学号// 设计学生类
class Student{
public://公共权限// 类中的属性和行为 我们统一称为成员// 属性 -> 成员属性/成员变量// 行为 -> 成员函数/成员方法string m_name; // 姓名int m_Id; // 学号// 行为void setName(string name){ // 设置姓名m_name = name;}void setId(int id){ // 设置学号m_Id = id;}void display(){ // 显示姓名和学号cout << "姓名:" << m_name << endl;cout << "学号:" << m_Id << endl;}
};int main() {// 创建一个具体学生 实例化对象Student s1;// 给s1对象 进行属性赋值操作s1.m_name = "张三";s1.m_Id = 2019001;// 显示学生信息s1.display();s1.setName("李四");s1.setId(2019002);s1.display();
}
运行结果:
PS D:\Work\c++\build\bin> ."D:/Work/c++/bin/app.exe"
姓名:张三
学号:2019001
姓名:李四
学号:2019002
PS D:\Work\c++\build\bin>
封装意义二:
类在设计时,可以把属性和行为放在不同的权限下,加以控制
访问权限有三种:
- public 公共权限
- protected 保护权限
- private 私有权限
#include <iostream>
using namespace std;/*三种访问权限:公共权限 public 成员 类内可以访问 类外可以访问保护权限 protected 成员 类内可以访问 类外不可以访问(儿子可以访问父亲中的保护内容)私有权限 private 成员 类内可以访问 类外不可以访问(儿子不可以访问父亲中的私有内容)
*/class Person{
public:void func() {m_Name = "张三";//公共权限m_Car = "拖拉机";//保护权限m_Password = 123456;//私有权限}
public:// 公共权限string m_Name;//姓名
protected:// 保护权限string m_Car;//汽车
private:// 私有权限int m_Password;//密码
};int main() {// 实例化具体对象Person p1;p1.m_Name = "呵呵哒";//类外可以访问(public)// p1.m_Car = "保时捷";//保护权限内容,在类外访问不到 error:成员"Person::m_Car"不可访问// p1.m_Password = 123456;//私有权限内容,在类外访问不到 error:成员"Person::m_Password"不可访问p1.func();//类外可以访问(public)return 0;
}
4.1.2 struct和class区别
- 在C++中struct和class唯一的区别就是默认的访问权限不同
区别:
- struct默认权限是公共权限
- class默认权限是私有权限
#include <iostream>
using namespace std;class C1{int m_A;// 默认权限 是私有
};struct C2{int m_A;// 默认权限 是公共
};int main() {/*在C++中struct和class唯一的区别就是默认的访问权限不同区别:struct默认权限是公共权限class默认权限是私有权限*/C1 c1;// c1.m_A = 10;// error:成员"C1::m_A"不可访问C2 c2;c2.m_A = 100;// ok return 0;
}
4.1.3 成员属性设置为私有
- 优点1:将所有成员属性设置为私有,可以自己控制读写权限
- 优点2:对于写权限,我们可以检测到数据的有效性
演示:控制读写权限
#include <iostream>
using namespace std;
/*成员属性设置私有优点1:将所有成员属性设置为私有,可以自己控制读写权限优点2:对于写权限,我们可以检测到数据的有效性
*/
// 人类
class Person{
public:// 设置姓名void setName(string name) {m_Name = name;}// 获取姓名string getName() const {// 返回类型为const,表示返回的是常量,不可修改返回值。return m_Name;// 返回m_Name的值。}// 获取年龄int getAge() const {// 返回类型为const,表示返回的是常量,不可修改返回值。return m_Age;// 返回m_Age的值。}// 设置偶像void setIdol(string idol) {m_Idol = idol;}
private:string m_Name;// 姓名 可读可写int m_Age = 18;// 年龄 只读string m_Idol;// 偶像 只写
};int main() {Person p;// 姓名设置p.setName("张三");cout<<"姓名:"<<p.getName()<<endl;// 姓名:张三// 获取年龄cout<<"年龄:"<<p.getAge()<<endl;// 输出年龄:18// 偶像设置p.setIdol("迪丽热巴");return 0; // 程序执行成功,返回0
}
演示:检测到数据的有效性,例如年龄设置为0-150之间
#include <iostream>
using namespace std;
/*成员属性设置私有优点1:将所有成员属性设置为私有,可以自己控制读写权限优点2:对于写权限,我们可以检测到数据的有效性
*/
// 人类
class Person{
public:// 设置姓名void setName(string name) {m_Name = name;}// 获取姓名string getName() const {// 返回类型为const,表示返回的是常量,不可修改返回值。return m_Name;// 返回m_Name的值。}// 设置年龄 0-150void setAge(int age) {if (age < 0 || age > 150) {cout << "年龄: "<< age << ",输入错误!" << endl;// 输出错误信息。return;}m_Age = age;}// 获取年龄int getAge() const {// 返回类型为const,表示返回的是常量,不可修改返回值。return m_Age;// 返回m_Age的值。}// 设置偶像void setIdol(string idol) {m_Idol = idol;}
private:string m_Name;// 姓名 可读可写int m_Age = 18;// 年龄 只读string m_Idol;// 偶像 只写
};int main() {Person p;// 姓名设置p.setName("张三");cout<<"姓名:"<<p.getName()<<endl;// 姓名:张三// 获取年龄p.setAge(250);cout<<"年龄:"<<p.getAge()<<endl;// 输出年龄:18// 偶像设置p.setIdol("迪丽热巴");return 0; // 程序执行成功,返回0
}
练习案例1:设计立方体类
- 设计立方体类(Cube)
- 求出立方体的面积和体积
- 分别用全局函数和成员函数判断两个立方体是否相等
1.类和对象-封装-设计案例1-立方体类
#include <iostream>
using namespace std;/*立方体类设计1.创建立方体类2.设计属性3.设计行为 获取立方体面积和体积4.分别利用全局函数和成员函数 判断两个立方体是否相等
*/
class Cube{
public:// 设置长void setL(int l){m_L=l;}// 获取长int getL(){return m_L;}// 设置宽void setW(int w){m_W=w;}// 获取宽int getW(){return m_W;}// 设置高void setH(int h){m_H=h;}// 获取高int getH(){return m_H;}// 获取立方体面积int getArea(){return 2*(m_L*m_W+m_L*m_H+m_W*m_H);}// 获取立方体体积int getVolume(){return m_L*m_W*m_H;}// 利用成员函数判断两个立方体是否相等bool isSameByClass(Cube &c){if(getL() == c.getL() && getW() == c.getW() && getH() == c.getH()) {return true;}else{return false;}}
private:int m_L;//长int m_W;//宽int m_H;//高
};// 利用全局函数判断 两个立方体是否相等
bool isSame(Cube &c1,Cube &c2) {if(c1.getL() == c2.getL() && c1.getW() == c2.getW() && c1.getH() == c2.getH()) return true; // 判断长宽高是否相等,如果相等则返回true,否则返回falseelse return false;
}int main() {Cube c1,c2;c1.setL(5);c1.setW(4);c1.setH(3);c2.setL(10);c2.setW(10);c2.setH(10);cout<<"c1的面积为:"<<c1.getArea()<<endl;cout<<"c1的体积为:"<<c1.getVolume()<<endl;cout<<"***************************"<<endl;cout<<"c2的面积为:"<<c2.getArea()<<endl;cout<<"c2的体积为:"<<c2.getVolume()<<endl;// 判断c1和c2是否相等// 利用全局函数判断bool ret = isSame(c1,c2);if(ret) cout<<"利用全局函数判断:c1和c2相等"<<endl;else cout<<"利用全局函数判断:c1和c2不相等"<<endl;// 利用成员函数判断ret = c1.isSameByClass(c2);if(ret) cout<<"利用成员函数判断:c1和c2相等"<<endl;else cout<<"利用成员函数判断:c1和c2不相等"<<endl;return 0;
}
2.类和对象-封装-设计案例2-点和圆关系案例
#include <iostream>
using namespace std;// 点和圆关系案例// 点类
class Point{
public:// 设置xvoid setX(int x) {m_X = x;}// 获取xint getX() {return m_X;}// 设置yvoid setY(int y) {m_Y = y;}// 获取yint getY() {return m_Y;}
private:int m_X;int m_Y;
};// 圆类
class Circle {
public: // 设置半径void setR(int r) {m_R = r;}// 获取半径int getR() {return m_R;}// 设置圆心void setCenter(Point center) {m_Center = center;}// 获取圆心Point getCenter() {return m_Center;}
private:int m_R;// 半径// 在类中可以让另一个类 作为本类中的成员Point m_Center;// 圆心
};
// 判断点和圆关系
void isInCircle(Circle& c, Point& p) {// 计算两点之间距离 平方int distance = (c.getCenter().getX() - p.getX()) * (c.getCenter().getX() - p.getX()) +(c.getCenter().getY() - p.getY()) * (c.getCenter().getY() - p.getY());// 计算半径的平方int rDistance = c.getR() * c.getR();// 判断关系if(distance == rDistance) {cout<<"点在圆上"<<endl;}else if(distance < rDistance) {cout<<"点在圆内"<<endl; }else {cout<<"点在圆外"<<endl;}
}
int main() {// 创建圆Circle c;c.setR(10);Point center;center.setX(10);center.setY(0);c.setCenter(center);// 创建点Point p;p.setX(10);p.setY(9);// 判断关系isInCircle(c,p);return 0;
}
进一步完善项目
- point.h
#pragma once
// 点类
class Point{
public:// 设置xvoid setX(int x);// 获取xint getX();// 设置yvoid setY(int y);// 获取yint getY();
private:int m_X;int m_Y;
};
- point.cpp
#include "point.h"// 设置x
void Point::setX(int x) {m_X = x;}
// 获取x
int Point::getX() {return m_X;}
// 设置y
void Point::setY(int y) {m_Y = y;}
// 获取y
int Point::getY() {return m_Y;}
- circle.h
#pragma once
#include "point.h"
// 圆类
class Circle {
public: // 设置半径void setR(int r);// 获取半径int getR();// 设置圆心void setCenter(Point center);// 获取圆心Point getCenter();
private:int m_R;// 半径// 在类中可以让另一个类 作为本类中的成员Point m_Center;// 圆心
};
- circle.cpp
#include "circle.h"
// 设置半径
void Circle::setR(int r) {m_R = r;}
// 获取半径
int Circle::getR() {return m_R;}
// 设置圆心
void Circle::setCenter(Point center) {m_Center = center;}
// 获取圆心
Point Circle::getCenter() {return m_Center;}
4.2 对象的初始化和清理
- 生活中我们买的电子产品都基本会有出厂设置,在某一天我们不用时候也会删除一些自己信息数据保证安全
- C++中的面向对象来源于生活,每个对象也都会有初始设置以及对象销毁前的清理数据的设置
4.2.1 构造函数和析构函数
对象的初始化和清理也是两个非常重要的安全问题
- 一个对象或者变量没有初始状态,对其使用后果是未知
- 同样的使用完一个对象或变量,没有及时清理,也会造成一定的安全问题
C++利用了构造函数和析构函数解决上述问题,这两个函数将会被编译器自动调用,完成对象初始化和清理工作。对象的初始化和清理工作是编译器强制要我们做的事情,因此如果我们不提供构造和析构,编译器会提供编译器提供的构造函数和析构函数是空实现
- 构造函数:主要作用在于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无须手动调用
- 析构函数:主要作用在于对象销毁前系统自动调用,执行一些清理工作
构造函数语法:类名(){}
- 构造函数,没有返回值也不写void
- 函数名称与类名相同
- 构造函数可以有参数,因此可以发生重载
- 程序在调用对象时候会自动调用构造,无须手动调用,而且只会调用一次
析构函数写法:~类名(){}
- 析构函数,没有返回值也不写void
- 函数名称与类名相同,在名称前加上符号~
- 析构函数不可以有参数,因此不可以发生重载
- 程序在对象销毁时候会自动调用析构,无须手动调用,而且只会调用一次
#include <iostream>
using namespace std;// 对象的初始化和清理
// 1.构造函数 进行初始化操作
class Person {
public:// 1. 构造函数// 没有返回值 不用写void// 函数名 与类名相同// 构造函数可以有参数,可以发生重载// 创建对象的时候,构造函数会自动调用,而且只调用一次Person() {cout<<"Person 构造函数的调用"<<endl;}// 2.析构函数 进行清理的操作// 没有返回值 不写void// 函数名和类名相同 在名称前加~// 析构函数不可以有参数的,不可以发生重载// 对象在销毁前,会自动调用析构函数,而且只会调用一次~Person () {cout<<"Person 析构函数的调用"<<endl;}
};// 构造和析构都是必须有的实现,如果我们不提供,编译器会提供一个空实现的构造和析构
void test01() {Person p;// 在栈上的数据,test01执行完毕后,释放这个对象
}int main() {test01();return 0;
}
执行结果:
PS D:\Work\c++\bin> .\app
Person 构造函数的调用
Person 析构函数的调用
PS D:\Work\c++\bin>
未完待续~
相关文章:
C++核心编程:类和对象 笔记
4.类和对象 C面向对象的三大特性为:封装,继承,多态C认为万事万物都皆为对象,对象上有其属性和行为 例如: 人可以作为对象,属性有姓名、年龄、身高、体重...,行为有走、跑、跳、说话...车可以作为对象,属性有轮胎、方向盘、车灯…...

机器学习实验3——支持向量机分类鸢尾花
文章目录 🧡🧡实验内容🧡🧡🧡🧡数据预处理🧡🧡代码认识数据相关性分析径向可视化各个特征之间的关系图 🧡🧡支持向量机SVM求解🧡🧡直觉…...
R语言【taxlist】——clean():移除孤立的记录
Package taxlist version 0.2.4 Description 对于 taxlist 类对象的操作可能会产生独立的条目。clean() 方法就是用来删除这样的条目,并恢复 taxlist 对象的一致性。 Usage clean(object, ...)## S4 method for signature taxlist clean(object, times 2, ...) A…...
CentOS 7.9 OS Kernel Update 3.10 to 4.19
date: 2024-01-18, 2024-01-26 原 OS Kernel 3.10 升级至 4.19 1.检查默认内核 检查 vmlinuz 版本 [rootlocalhost ~]# grubby --default-kernel /boot/vmlinuz-3.10.0-1160.105.1.el7.x86_64 [rootlocalhost ~]#检查 Linux 内核版本 [rootlocalhost ~]# uname -a Linux loc…...

k8s---安全机制
k8s的安全机制,分布式集群管理工具,就是容器编排。安全机制的核心:APIserver。为整个集群内部通信的中介,也是外控控制的入口。所有的机制都是围绕apiserver来进行设计: 请求api资源: 1、认证 2、鉴权 …...

GitHub 一周热点汇总第7期(2024/01/21-01/27)
GitHub一周热点汇总第7期 (2024/01/21-01/27) ,梳理每周热门的GitHub项目,离春节越来越近了,不知道大家都买好回家的票没有,希望大家都能顺利买到票,一起来看看这周的项目吧。 #1 rustdesk 项目名称:rust…...
kotlin data clas 数据类
data class 介绍 kotlin 中 data class 是一种持有数据的特殊类 编译器自动从主构造函数中声明的所有属性导出以下成员: .equals()/.hashCode() 对 .toString() 格式是 "User(nameJohn, age42)" .componentN() 函数 按声明顺序对应于所有属性。…...

Java基础知识-异常
资料来自黑马程序员 异常 异常,就是不正常的意思。在生活中:医生说,你的身体某个部位有异常,该部位和正常相比有点不同,该部位的功能将受影响.在程序中的意思就是: 异常 :指的是程序在执行过程中,出现的非正常的情况,…...

跟着cherno手搓游戏引擎【12】渲染context和首个三角形
渲染上下文: 目的:修改WindowsWindow的结构,把glad抽离出来 WindowsWindow.h:新建m_Context #pragma once #include "YOTO/Window.h" #include <YOTO/Renderer/GraphicsContext.h> #include<GLFW/glfw3.h> #include…...

MybatisPlus二级映射和关联对象ResultMap
文章目录 一、业务背景1. 数据库表结构2. 需求 二、使用映射直接得到指定结构三、其他文件1. Mapper2. Service3. Controller 四、概念理解一级映射二级映射聚合 五、标签使用1. \<collection\> 标签2. \<association\> 标签 在我们的教程中,我们设计了…...
低代码开发业务在AIGC时代的应用
随着人工智能和图形计算能力的快速发展,低代码开发平台在AIGC(人工智能,物联网,大数据和云计算)时代中扮演着至关重要的角色。本文将介绍低代码开发业务的概念和优势,探讨其在AIGC时代的应用及其对传统软件…...

惠普1536dnf MFP报52扫描仪错误维修
如果您使用的惠普HP LaserJet 1536dnf MFP打印机可能会遇到“52扫描仪错误”的提示。这个错误可能会阻止你使用打印机的扫描功能。在这里,我将提供一些有用的解决方法来帮助大家去解决这个问题。-----吴中函 故障描述: 一台某单位正在使用的惠普HP LaserJet 1536dnf MFP黑白…...

【MIdjourney】五个特殊物体关键词
1.碳酸(Carbonate) 这一词语的本意是指包含碳(C)、氧(O)和氢(H)元素的化合物。而在MIdjourney中添加该词汇会使得生成的图片具有水滴效果且富有动态感。 2.灯丝(Filament) Filament效果可能包括更逼真的…...

2024/1/27 备战蓝桥杯 1
目录 求和 0求和 - 蓝桥云课 (lanqiao.cn) 成绩分析 0成绩分析 - 蓝桥云课 (lanqiao.cn) 合法日期 0合法日期 - 蓝桥云课 (lanqiao.cn) 时间加法 0时间加法 - 蓝桥云课 (lanqiao.cn) 扫雷 0扫雷 - 蓝桥云课 (lanqiao.cn) 大写 0大写 - 蓝桥云课 (lanqiao.cn) 标题…...
初学数据结构:Java对象的比较
目录 1. PriorityQueue中插入对象2. 元素的比较2.1 基本类型的比较2.2 对象比较的问题 3. 对象的比较3.1 基于Comparable接口类的比较3.2 基于比较器比较3.3 三种方式对比 4. 集合框架中PriorityQueue的比较方式5. 使用PriorityQueue创建大小堆,解决TOPK问题 【本节…...
mac 10.15.7 Unity 2021.3.14 XCode 12.4 -> Unity IOS 自动安装 Cocoapods 失败解决方法
自己这两天在用Unity开发IOS时,遇到了安装Cocoapods失败的问题,记录一下问题及解决方法,便于自己后续查看,以及有相同遭遇的人查看 发生场景:打开 unity,触发自动安装 Cocoapods -> 安装失败(…...
Elasticsearch 中使用MustNot等同于不登录遇到的坑
1、在写关键词推荐时,需要把当前文章过滤掉,不能再推荐自己的文章,所以再es中需要用到 MustNot属性查询 /// <summary> /// 服务中心es检索 /// </summary> /// <param name="input"></param> /// <returns></…...

java抽象工厂实战与总结
文章目录 一、工厂模式(三种)1.简单工厂模式1.1 概念:1.2 使用场景:1.3 模型图解:1.4 伪代码: 2.工厂方法模式2.1 概念:2.2 使用场景:2.3 模型图解:2.4 伪代码 3.抽象工厂…...
Compose | UI组件(六) | 选择框
文章目录 前言Checkbox 复选框的含义Checkbox 复选框的使用Switch 单选框的含义Switch 单选框的使用Slider 滑竿组件的含义Slider 滑竿组件的使用 总结 前言 随着移动端的技术不断更新迭代,Compose也运用的越来越广泛,很多人都开始学习Compose 本文主要…...

C++拷贝构造函数、赋值学习整理:
拷贝构造函数: 概念: 构造函数的第一个参数,是类本身的const引用(一般情况下没有其他参数,少数情况:其他参数必须有默认值!)称此类构造函数为拷贝构造函数 特征: 1&am…...

Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧
上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...