C++类和对象下(初始化列表,静态成员,explicit关键字,友元)

news2024/11/29 16:40:51

C++类和对象下[初始化列表,静态成员,explicit关键字,友元]

  • 一.初始化列表
    • 1.为什么会有初始化列表
    • 2.初始化列表的语法形式
    • 3.没有默认构造函数的自定义成员变量
    • 4.初始化列表是成员变量定义的地方
    • 5.初始化列表可以跟函数体内定义搭配使用
    • 6.初始化列表执行的顺序
    • 7.总结+建议
  • 二.静态成员变量和静态成员函数
    • 1.static成员变量的引出
    • 2.static成员变量的特性
    • 3.对于解决以上需求: static成员变量的不足
    • 3.匿名对象
    • 4.static成员函数
    • 5.总结
    • 6.OJ 计算1+2+...+n
  • 三.explicit关键字
    • 1.一个奇怪的现象
    • 2.用途
    • 3.为什么要有explicit呢?
  • 四.友元
    • 1.友元函数
    • 2.友元类
      • 1.语法:
      • 2.实例:
      • 3.总结
    • 3.内部类
      • 1.语法
      • 2.实例
      • 3.总结:
  • OJ题的优化

一.初始化列表

1.为什么会有初始化列表

在这里插入图片描述
我们在Date中添加了两种成员变量:
分别是引用类型和const类型
为什么编译器会报错呢?
是不是因为编译器默认生成的构造函数不行呢?
那我们自己去实现一下怎么样?
在这里插入图片描述
还是不行:它说引用和const类型的对象定义时必须初始化
对啊,因为引用不能改变指向,所以必须在初始化引用的时候就要指定好对象
const类型的变量的值是不能修改的,因此初始化时也必须设好值

那么我们应该怎么办呢?

针对于这个问题C++创始人规定了初始化列表这一语法:

为了解决有些成员变量在定义的时候必须初始化!!!

2.初始化列表的语法形式

在这里插入图片描述

Date(int year = 1, int month = 2, int day = 3)
	:_year(year)
	, _month(month)
	, _day(day)
	, _ref(_year)
	, _cint(_year)
	{
		//函数体内可以继续进行代码的书写
	};
第一个是冒号
后面是逗号

在这里插入图片描述
这样我们的程序就可以通过了
其实初始化列表还解决了下面这个问题

3.没有默认构造函数的自定义成员变量

在这里插入图片描述
C++类和对象中(构造函数,析构函数,拷贝构造函数)详解
在这里插入图片描述
那么问题来了:
如果这个Stack类没有默认构造函数呢?
会发生编译错误
在这里插入图片描述
那么怎么办呢?

其实我们仔细想一想:
这个MyQueue类中的Stack类没有了默认构造函数,不就意味着这个Stack类在我们这个MyQueue类定义的时候必须初始化吗?

所以这个时候初始化列表就派上用场了

MyQueue(int capacity1, int capacity2,int size)
	:_st1(capacity1)
	,_st2(capacity2)
	,_size(size)
	{
	};

在这里插入图片描述
这样就可以解决这个问题了
其实就算是你这个Stack类有默认构造函数,但是如果我就是想自己去传参调用你的这个默认构造函数.也是可以这样做的
在这里插入图片描述
如果没有初始化列表这一语法,我们在声明的时候去调用Stack类的传参构造函数呢?
在这里插入图片描述
会直接报错

4.初始化列表是成员变量定义的地方

那么初始化列表到底是什么身份呢?
这么强大

初始化列表是成员变量定义的地方

我们之前提到过:
在这里插入图片描述
在这里插入图片描述
也就是说只要你这个类有成员变量,就一定会走构造函数,只要你走构造函数,就一定会走构造函数当中的初始化列表

而成员变量就是在初始化列表中定义的,也就是在初始化列表中分配的空间!!

5.初始化列表可以跟函数体内定义搭配使用

那么既然初始化列表这么强大,可不可以不要函数体了呢?
构造函数只留一个初始化列表不就行了吗?
当然不可以

比如:下面的Stack类

	Stack(int capacity = 1)
		:_a((int*)malloc(sizeof(int)*capacity))
		,_capacity(capacity)
		,_top(0)
	{};

在这里插入图片描述
你这不是也可以吗,这是好的情况
万一我申请空间太大,申请失败了呢?

wzs::Stack st(1000000000000000000);

我们在这里直接申请这么大的空间
在这里插入图片描述
那么该怎么办呢?
在初始化列表里面去检查吗?
初始化列表是定义成员变量给成员变量开辟空间的地方,
你在里面检查_a是否等于空指针
你这不是大材小用吗
直接让_a在函数体内初始化它不香吗?

也就是这样

Stack(long long capacity = 1)
	:_capacity(capacity)
	,_top(0)
{
	_a = ((int*)malloc(sizeof(int) * capacity));
	if (_a == nullptr)
	{
		perror("malloc fail");
		exit(-1);
	}
};
wzs::Stack st(1000000000000000000);

开辟空间失败:
在这里插入图片描述
开辟空间成功:

wzs::Stack st(10);

在这里插入图片描述
也就是说初始列表和构造函数的函数体是相辅相成的,
类似的关系:引用和指针

所以日常中:对于成员变量来说
大多数情况下我们都是用初始化列表搞定
剩下那些只能用函数体去初始化的就用函数体去搞定

6.初始化列表执行的顺序

成员变量在类中声明次序就是其在初始化列表中的初始化顺序,
与其在初始化列表中的先后次序无关

大家可以看一下这个题,这是《剑指offer》上的一道题目
在这里插入图片描述
答案:
n1:随机值
n2:0
因为成员变量在类中声明次序就是其在初始化列表中的初始化顺序,
所以n1先被初始化,然后n2才被初始化
也就是说
它们在初始化列表中的执行次序如下:

n1 = n2+2;
n2 = 0;

而n1和n2在还没有被初始化时都是随机值
因此n1就是随机值,而n2被初始化为了0
在这里插入图片描述

7.总结+建议

在这里插入图片描述
这个注意当中的第一条和这个初始化列表跟函数体内定义的区别这一条:
也就是说如果有人这么写:
在这里插入图片描述
也就是说初始化列表中,成员变量只能初始化一次,因此叫做初始化列表
而函数体中,成员变量可以赋值很多次,所以在函数体中只能被称为赋值初值,而不能被称为初始化!!!

也就是说对于我们的这个构造函数来说

Date(int year = 1, int month = 2, int day = 3)
	: _ref(_year)
	, _cint(_year)
	{
		_year=year;
		_month=month;
		_day=day;
	};
private:
	int _year;
	int _month;
	int _day=26;
	int& _ref;
	const int _cint;

本质上编译器是这样进行的:

Date(int year = 1, int month = 2, int day = 3)
	:_year(随机值)
	,_month(随机值)
	,_day(缺省值26)
	,_ref(_year)
	, _cint(_year)
	{
		//下面是重新对_year,_month,_day进行再次赋值
		_year=year;
		_month=month;
		_day=day;
	};
private:
	int _year;
	int _month;
	int _day=26;
	int& _ref;
	const int _cint;

也就是说构造函数中:
初始化列表是成员变量定义的地方,每一个成员变量都需要走初始化列表

如果在初始化列表当中我们没有显式定义该成员变量,就会使用该成员变量声明时给的缺省值,如果没有缺省值,那么就会使用编译器给的随机值

函数体内定义其实本质上是给成员变量进行第二次赋值

也就是像这样

int var = 随机值; //初始化列表
var=1;//函数体内定义

其实翻来覆去就只有一句话:初始化列表是成员变量定义的地方
函数体内是成员变量可以进行二次赋值的地方

二.静态成员变量和静态成员函数

在这里插入图片描述
我们出现了一个需求:计算一个类实例化出了多少个对象

1.static成员变量的引出

其实方法很简单:只需要定义一个全局变量count=0,然后在这个类的所有的构造函数当中都让这个count++
最后count的数值就是该类实例化出的对象的个数
在这里插入图片描述
这样是可行的,但是并不好
为什么呢?
因为这个变量count是一个全局变量,也就是说这个count可以在程序的任意位置访问并修改

所以有可能会出现这种情况:
在这里插入图片描述
这个func函数中它成功地把我count这个全局变量给修改了
导致最后得出的答案少了1

也就是我们无法避免这种极端情况的发生
那怎么办呢?

而且把这个count定义为成员变量也是不行的
因为每一个对象都有自己的count,都是++的自己的count

那么有没有一种成员变量是为我这个类实例化出的所有的对象所共享的呢?
static成员变量就出现了

2.static成员变量的特性

在这里插入图片描述
既然我们了解了static成员变量的特性

3.对于解决以上需求: static成员变量的不足

那么我们该怎么解决上面那个需求呢?
在这里插入图片描述
但是还是有一个问题
我在这里是把_count这个静态成员变量的访问属性设置为公有了,但是也防不住会出现下面这种情况:
在这里插入图片描述
是,你是把_count这个全局变量放到了你A这个类的内部
但是你把它的访问属性设置为了公有,
因此我func想改你这个_count,我只需要加上你A这个类域,我依然能改,你拦不住我

那怎么办呢?
把_count放到私有属性下:

3.匿名对象

在这里插入图片描述
是,我func现在是改不了了,但是你main函数也访问不了啊
怎么办呢?
1.封装get函数
在这里插入图片描述
不错,而且我func函数也无法修改你这个count了
但是你这样的前提是你这个main函数里面有一个A的对象啊
这样你才能用对象.去访问这个get函数啊

可是如果我原本就没有在这个main函数里面创建一个A类型的对象
那你就只能这样了
在这里插入图片描述
可是你说我为了能够得到这个类到底实例化出了多少个对象,还要去特意在我main函数里面特意实例化出一个对象,
太挫了吧

而且我还要考虑取名字的事情,而且我创建这个对象只需要让它完成者一个任务即可,我后续也不想用它,能不能让它在执行完这个任务之后就销毁呢?

这就可以用到匿名对象了
在这里插入图片描述
匿名对象就是A()
它的特点是:
1.不用取名字
2.它的生命周期只有

cout << wzs::A().GetCount()-1 << endl;

这一行
完美符合了我刚才的需求

请注意:但是这个-1有点碍眼,让我这个代码不是很帅
显得我这个人的水平很挫

怎么办呢?
可是想要访问这个get函数就是必须创建一个对象
然后用对象.才能访问啊

能不能不用对象呢?
于是static成员函数出现了

4.static成员函数

在这里插入图片描述
在这里插入图片描述
这样就能把-1这个影响我代码美观性地东西就消失了
到了这里我们这个需求就完美解决了

5.总结

在这里插入图片描述
到了这里,大家就能对下面这张图片有更深刻的理解了
在这里插入图片描述

6.OJ 计算1+2+…+n

下面我们来做一道OJ题来巩固一下上面的知识
求1+2+3+…+n
在这里插入图片描述
这么多限制条件,怎么办呢?
其实这个题的本意就是让我们利用类的静态成员来解决这个问题

注意:牛客网的编程题所采用的编译器是支持变长数组的,VS编译器是不支持变长数组的
在这里插入图片描述
在这里插入图片描述
但是这个代码还不是特别好,当我们介绍完内部类之后,我们还会对这个代码进行进一步修改

三.explicit关键字

1.一个奇怪的现象

在这里插入图片描述

wzs::B b2 = 1;
竟然能这么创建一个对象,这是怎么做到的呢?

其实:
我们之前在C++入门-引用中介绍过:

在这里插入图片描述
因此我们可以认为是这样进行的
在这里插入图片描述
那么下面的问题就是
为什么1这个内置类型能隐式类型转换为我B这个类类型呢?

其实这里有一个规则:

当某个类的构造函数可以只传入一个参数时,而且这个参数的类型跟我这个内置类型相同的时候
就可以发生这个类类型对象和这个内置类型变量之间的隐式类型转换

下面这个例子能帮大家更好地去理解
class A
{
public:
    构造函数第1种情况:
    A(int val) //单参数构造函数
    :_var1(val)
    {}         
    A(int val1,int val2 = 2,int val3 = 3)//半缺省,且只传一个参数即可完成对象的构造
    :_var1(val1)
    ,_var2(val2)
    ,_var3(val3)
    {}
    A(int val1 = 1,int val2 = 2,int val3 = 3)//全缺省,这个构造函数允许只传一个参数进行构造
    :_var1(val1)
    ,_var2(val2)
    ,_var3(val3)
    {}
  private:
      int _var1;
      int _var2;
      int _var3;
};
它们都允许: A a = 1;
但是当这个内置类型跟我这个参数的类型不匹配时:
例如   A a = nullptr; 这样就无法发生隐式类型转换

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
而且还有一种书写方式:列表初始化

zs::A a={2023,11,3};

在这里插入图片描述
这个本质也跟上面那个内置类型1隐式转换为A类类型的对象一样:
在这里插入图片描述
可是有一个问题啊
你跟我讲这么一大堆,有什么用呢?

2.用途

我们这里先用一下STL中的vector容器
当我们在leetcode做OJ题的时候:

#include <vector>
int main()
{
	vector<zs::A> v;

	//当我们在leetcode做OJ题时:

	//1.在没有学习这个知识之前我们平常的做法
	zs::A a(1);
	v.push_back(a);

	//2.学习了匿名对象后 
	v.push_back(zs::A(1));//  这代码写起来爽了很多

	//3.学习了内置类型和自定义类型之间的隐式转换后
	v.push_back(1);//     这代码写起来太爽了,可是只有在构造函数允许只传一个参数的时候才可以啊

	//4.学习了列表初始化隐式类型转换为类类型对象后
	v.push_back({ 2023,11,3 });//   爽飞了  ,而且允许只传一个参数对我无效
	return 0;
}

在这里插入图片描述
可见这个知识是很棒的

3.为什么要有explicit呢?

那么你介绍的这个explicit是什么呢?
他有什么用呢?
在这里插入图片描述
在这里插入图片描述

四.友元

在这里插入图片描述

1.友元函数

我们之前在介绍运算符重载的时候提到过友元函数

当时是为了解决日期类的流插入和流提取运算符不能定义在类内,但是还想要访问这个类的成员变量的矛盾
详细的请况大家可以去看这篇博客:
C++类和对象中:运算符重载+const成员函数+日期类的完善
在这里插入图片描述

2.友元类

1.语法:

这里以C类是B类的友元为例
class B
{
	friend class C;//友元声明不受类访问限定符的限制
}
class C
{
   B b;//需要有一个B类的对象
   //然后想要访问B类的成员变量或者成员函数的时候就可以用这个B类的对象.去访问
}

2.实例:

namespace zs
{
class B
{
public:
	friend class C;
private:
	void FuncOfB()
	{
		cout << "private:  FuncOfB()调用" << endl;
	}
	int _bint = 1;
	static int _StaticInt;
};
int B::_StaticInt = 5;
class C
{
	public:
		void SetMemberOfB(int val)
		{
			b._bint = val;
			B::_StaticInt = val;
		}
		void ReadMemberOfB()
		{
			cout << b._bint << endl;
			cout << B::_StaticInt << endl;//只能这样访问
		}
		void ReadFuncOfB()
		{
			b.FuncOfB();
		}
	private:
		int _cint;
		B b;
	};
}
int main()
{
	zs::C c;
	c.SetMemberOfB(100);
	c.ReadMemberOfB();
	c.ReadFuncOfB();
	return 0;
}

3.总结

关于友元类的访问方法其实大家只需要记住一点:

友元类:我是你的朋友,
我也只是能够访问你的私有成员而已
访问方法跟普通类访问你的公有成员的方法一样

在这里插入图片描述
注意:友元关系是单向的,不具有交换性
因此上面的类B就无法访问类C的私有成员

3.内部类

1.语法

在这里插入图片描述

2.实例

namespace zs
{
	//注意:D是外部类,E是内部类.E天生就是D的友元,但是默认情况下D是不能访问E的,除非在E中声明D是E的友元类
	class D
	{
	public:
		class E
		{
		public:
			void GetStaticMemberOfD()
			{
				cout << _StaticInt << endl;
				//yes  这是上述第3条特性:  内部类可以直接访问外部类的static成员,不需要外部类的对象/类名
				//cout << _NonStaticInt << endl;//err  内部类不能直接访问外部类的非static成员
				cout << d._NonStaticInt << endl;//yes  只能用对象.去访问

				//也就是说内部类访问外部类:只不过是静态成员可以直接访问而已,非静态成员的访问跟普通类访问外部类的非静态成员的方法一样
			}
		private:
			zs::D d;
		};
	private:
		static int _StaticInt;
		int _NonStaticInt = 10;
	};
	int D::_StaticInt = 1;
}

3.总结:

在这里插入图片描述
其实C++不常用内部类

OJ题的优化

学习了内部类之后,我们就能对那道OJ题进行优化
在这里插入图片描述
在这里插入图片描述

以上就是类和对象下的全部内容,希望能对大家有所帮助!!!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

KT6368A蓝牙芯片发送指令设置中文蓝牙名是乱码 这个要如何处理

目录 一、KT6368A蓝牙芯片为什么发送at指令设置中文spp蓝牙名&#xff0c;是乱码 这个要如何处理 第一步&#xff0c;在pc端新建一个txt文档&#xff0c;将您需要的名字&#xff0c;汉字打出来&#xff0c;另存为UTF-8编码 第二步&#xff0c;使用winhex软件&#xff0c;当然…

JVS智能BI(自助式商业分析)本周更新内容已上线

在数据分析与可视化的世界中&#xff0c;我们始终在寻找新的创新与突破&#xff0c;以帮助用户更高效、更直观地理解数据&#xff0c;洞察业务的深层逻辑。本周更新包含了一系列的新功能、优化及bug修复&#xff0c;更新如下&#xff1a; 新增: 1.新增图表分类功能&#xff1…

宝宝洗衣机哪个牌子质量好?小型洗衣机质量排名

说起洗衣服&#xff0c;大部分的家庭都会备有一台洗衣机&#xff0c;不过如果有婴儿的话&#xff0c;贴心的宝妈宝爸也会特意将宝宝的衣服与大人的衣服分开来进行清洗。很多妈妈都会自己动手洗。由于婴儿的皮肤比较娇嫩、敏感&#xff0c;所以儿童的衣物与成人的衣物混合使用&a…

视频特效制作软件:After Effects 2024 mac中文版新增功能

After Effects 2024 mac是一款专业的视频特效和动态图形设计软件&#xff0c;它可以帮助用户创建各种令人惊叹的视觉效果&#xff0c;例如粒子系统、合成特效、绿屏抠像等。该软件支持动画制作&#xff0c;包括关键帧动画、形状动画、运动跟踪等工具&#xff0c;可以创建复杂的…

数据库实验报告(五)

1、实验目的 &#xff08;1&#xff09; 掌握对聚集函数的使用 &#xff08;2&#xff09; 掌握对分组的使用 &#xff08;3&#xff09; 掌握非关联子查询的用法&#xff0c;了解相关的连接谓词 2、实验预习与准备 &#xff08;1&#xff09; 了解Max&#x…

面试算法53:二叉搜索树的下一个节点

题目 给定一棵二叉搜索树和它的一个节点p&#xff0c;请找出按中序遍历的顺序该节点p的下一个节点。假设二叉搜索树中节点的值都是唯一的。例如&#xff0c;在图8.9的二叉搜索树中&#xff0c;节点8的下一个节点是节点9&#xff0c;节点11的下一个节点是null。 分析&#xf…

Web开发介绍详细介绍

Web开发介绍 1 什么是web开发 Web&#xff1a;全球广域网&#xff0c;也称为万维网(www World Wide Web)&#xff0c;能够通过浏览器访问的网站。 所以Web开发说白了&#xff0c;就是开发网站的&#xff0c;例如下图所示的网站&#xff1a;淘宝&#xff0c;京东等等 那么我们…

常见接口测试面试题

1、按你的理解&#xff0c;软件接口是什么&#xff1f; 答&#xff1a; 就是指程序中具体负责在不同模块之间传输或接受数据的并做处理的类或者函数。 2、HTTP和HTTPS协议区别&#xff1f; 答&#xff1a; https协议需要到CA&#xff08;Certificate Authority&#xff0c;证书…

犀牛8 for Mac – 强大的三维建模软件,轻松实现创意设计

你是否正在寻找一款功能强大、易于使用的三维建模软件&#xff1f;犀牛8 for Mac是你的不二选择&#xff01;作为最新版本的犀牛系列软件&#xff0c;它汇集了众多令人惊叹的特性&#xff0c;让你能够轻松实现自己的创意设计。 犀牛8 for Mac拥有丰富而强大的三维建模工具&…

【Python基础】变量基本使用

变量 1.变量定义02. 变量的类型2.1 变量类型的演练 —— 个人信息2.2 变量的类型2.3转义字符 3.变量输入输出3.1变量格式化输出 4.变量命名 1.变量定义 变量定义 • 在 Python 中&#xff0c;每个变量 在使用前都必须赋值 在使用前都必须赋值&#xff0c;变量 赋值以后 该变量…

R语言使用HTTP爬虫IP写一个程序

R语言爬虫是指使用R语言编写程序&#xff0c;自动从互联网上获取数据的过程。在R语言中&#xff0c;可以使用三个主要的包&#xff08;XML、RCurl、rvest&#xff09;来实现爬虫功能。了解HTML等网页语言对于编写爬虫程序也非常重要&#xff0c;因为这些语言是从网页中提取数据…

解决方案中排版的灵魂的---样式的设置

word样式是一系列字符格式和段落格式的集合&#xff0c;可以在编排重复格式的时候套用样式&#xff0c;减少重复化的操作。 一、word样式 二、样式基准 样式基准是最基本或原始的文字段落格式&#xff0c;文档中的其他样式以此为基础创建。 我新建样式&#xff0c;如果选择样…

Go的Defer简介

什么是延期&#xff1f; Defer 语句用于在存在 defer 语句的周围函数返回之前执行函数调用。该定义可能看起来很复杂&#xff0c;但通过示例就很容易理解。 例子 package mainimport ( "fmt" )func finished() { fmt.Println("Finished finding largest&qu…

XR Interaction ToolKit

一、简介 XR Interaction Toolkit是unity官方的XR交互工具包。 官方XRI示例地址&#xff1a;https://github.com/Unity-Technologies/XR-Interaction-Toolkit-Examples 2023.3.14官方博客&#xff0c;XRIT v2.3 https://blog.unity.com/engine-platform/whats-new-in-xr-int…

ERR operation not permitted

ERR operation not permitted E:\Document_Redis_Windows\redis-2.4.5-win32-win64\64bit redis.conf auth 123456 redis requirepass_requirepass redis-CSDN博客

PP-Matting:trimap free的高精度自然图像抠图

论文&#xff1a;https://arxiv.org/abs/2204.09433 代码&#xff1a;https://github.com/PaddlePaddle/PaddleSeg 1、动机 在自然图像抠图领域&#xff0c;大多数方法都是基于Trimap来做抠图&#xff0c;这种trimap-based的方式在抠图时还需要用户绘制一个trimap作为模型输入&…

Vue项目运行时报错:‘vue-cli-service‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件

报错原因及解决 1.package.json 文件中未定义依赖项vue/cli-service&#xff0c;因此在 npm install 之后并没有安装vue/cli-service 依赖&#xff1b; 解决&#xff1a;项目目录下执行命令&#xff0c;npm i -D vue/cli-service。2.第1步排查后&#xff0c;还是报同样的错&a…

Django-vue-admin 滚动监听,锚点定位目录

就是实现滑动内容&#xff0c;目录也跟着滚动&#xff0c;同时点击目录&#xff0c;内容会滑动到指定位置 试过很多&#xff0c;反正都不适用Django-vue-admin框架&#xff0c;唯有这个功能可以&#xff0c;只是样式按照自己想要的改改就行&#xff0c; https://blog.csdn.ne…

【深度学习】快速制作图像标签数据集以及训练

快速制作图像标签数据集以及训练 制作DataSet 先从网络收集十张图片 每种十张 定义dataSet和dataloader import glob import torch from torch.utils import data from PIL import Image import numpy as np from torchvision import transforms import matplotlib.pyplot…

这才是当今生成式人工智能的根本性问题!

原创 | 文 BFT机器人 01 引言 近年来&#xff0c;生成式人工智能产品层出不穷&#xff0c;ChatGPT火爆出圈后&#xff0c;百度、谷歌等科技大佬争相研究生成式人工智能产品&#xff0c;将该技术的普及程度提升到了一个新的水平。然而&#xff0c;生成式人工智能的运营需要高昂…