首页 > 编程语言 >c++和c的不同及c++扩展内容

c++和c的不同及c++扩展内容

时间:2024-11-14 15:19:29浏览次数:3  
标签:p1 函数 对象 成员 扩展 c++ int 内容 cout

头文件不同

c++采用iostream库,并且作用与std领域中;

标准格式:

Using namespace std

#include<iostream>

Int main()

{

xxxxx

System("pause");

Return 0;

}

提出了四个作用区域

全局区 代码区 栈区 堆取

全局区:

用来存放所有的全局变量,或宏定义代码,静态变量和常量;

代码区:

用来存储所有的代码;

栈区:

由编译器自动分配,用于存储局部变量和函数值等:

//再利用函数时不能让其返回值为其中的局部变量;

因为当函数执行完后,该内存被释放;无法找到该变量内存;

堆区:

由程序员分配和释放的区

引入新的变量类型

Bool string new

布尔型变量 标志真假 真表示1 假表示0

字符串类型变量 string str;直接定义一个类型变量;

New 动态申请内存 new int(10);申请一个存10的int型空间内存,并返回一个地址;new int[10]申请10个连续空间的数组;当要释放该内存时,利用delete p;若为一段连续的数组空间为 delet []p;

输出保留小数点方式

#include <iomanip>

  1. //两位小数

 

  1. //第一种写法
  1. cout<<setiosflags(ios::fixed)<<setprecision(2);
  1. //第二种写法
  1. cout.setf(ios::fixed);
  2. cout<<setprecision(2);
  1. //第三种写法
  1. cout<<fixed<<setprecision(2);

setprecision(n)

 功能:控制浮点数显示的有效数字个数。

fixed

setprecision(n)和fixed合用的话可以控制小数点后有几位

cout<<setiosflags(ios::fixed);

cout.setf(ios::fixed);

cout<<fixed;

提出了引用这一用法

给一个变量取别名,并且该别名与原名起同等作用,

int b=10;int&a=b;即b为原名,a为别名,需要注意的是,该别名只能代表一个变量,其本质为指针量,指向了该变量的内存地址,并且对该数操作时,不用的带上指针*;int&a=10;是不允许的

再利用引用作为函数返回值时,是不被允许的,由于函数中的局部变量作用在栈上,执行完后该内存被释放,不能返回主函数中;

例如:

Int&fac()

{

Static Int a=10;

Return a; //此时a相当于a的别名,即别名与原名可相同

}

Void main ()

{

Int &p=fac();//此时由于编译器的保存机制,第一次输出时会保留a的值,第二次输出则为乱码,此时p为a的别名,即p为指向a的指针常量,

p=100;//此时相当于a=100;

Fac()=1000;//fac函数返回的是a的别名,即a=1000,那么对应的别名p=1000

}

若我们将作用于栈上的局部变量转化为作用在全局上的静态变量时,此时a值可返回,因为内存不被释放,即在前加static;

若将引用作为函数参数,

#include<iostream>

#include<string>

using namespace std;

void fac(int&a,int&b){

 a=10;

 b=100;

return;

}

int main(){

int a,b;

fac(a,b);

cout<<a;

cout<<b;

return 0;

}

此时相当于对传入的实参取了两个别名a,b;对别名a与b的操作同样对原名实参有相同作用;与指针传参相同。传参方式可以分为三类,直接传参,指针传参,引用传参;

若我们不想让某个传入函数中的值发生变化,可以在其前加上const;之后我们就不能对其操作了;

goto语句

跳转语句

格式:

Goto +标识符

在需要跳转的地方加上:

标识符:

类与对象

利用class或struct封装  类别

一个类别包含属性 行为 访问限制

其中属性是共有的特征即为声明的变量类型;行为是对属性进行操作的函数;

访问限制包含public private protected  其中这三种都可以在类中进行访问和操作;

但是private protected 只能作用在类中,即只能在class中;我们可以将属性放在private中,然后利用public中的函数调用来实现对private中的变量的赋值和读取;

封装好类后;我们可以在主函数中利用类来实例化一个对象,在对对象的属性进行操作;

匿名对象

不用写名字:

Person ();//匿名对象 使用后立即释放

类中调用其他类别:

例如:

#include<iostream>

#include<cmath>

using namespace std;

//封装点类

class point{

private:

    double x,y;

public:

    //获取 读出x,y

    void set_x(double x1){

        x=x1;

    }

    void set_y(double y1){

        y=y1;

    }

    double gets_x(){

        return x;

    }

    double gets_y(){

        return y;

    }

};

//封装圆类

class circule{

private:

    double rr;

    point center;  //调用其他类

public:

    //获取 读半径

    void set_r(double r){

        rr= r;

    }

    double gets_rr(){

        return rr;

    }

    //获取圆心 设置圆心

    void set_center(point center1){

        center=center1;

    }

    point gets_center(){

        return center;

    }

};

//判断点和圆关系

void result(circule c1,point p1){

    //计算两点距离

    double distance;

   distance= pow(c1.gets_center().gets_x()-p1.gets_x(),2)+pow(c1.gets_center().gets_y()-p1.gets_y(),2);

    if(pow(c1.gets_rr(),2)==distance)

        cout<<"点在圆上"<<endl;

    else if (c1.gets_rr()*c1.gets_rr()<distance)

        cout<<"点在圆外"<<endl;

    else cout<<"点在圆内"<<endl;

}

int main(){

  point p1,p2; //p1表示待测点 p2便是圆心

  circule c1;  //圆

  //设置参数

  c1.set_r(10);

  p1.set_x(10);

  p1.set_y(10);

  p2.set_x(10);

  p2.set_y(0);

  c1.set_center(p2);

 result(c1,p1);

    system("pause");

    return 0;

}

即一个类可以调用另一个类,从而通过该类来设置其中的其他属性;例如圆类中调用了点类,来实现定义圆心,通过访问点类中的其他元素实现对圆心的设置;其次;类可以作为函数的返回值,和形参;这一点与struct相似;但是struct默认作用域为public,class默认为private;

构造函数和析构函数

在初始化对象时,需要写一个构造函数(必须要有的,若自己不写,编译器会帮你写,并且为一个空函数),当对象需要被清理时(对象被回收时),调用析构函数(若不写编译器会帮你写,并且为空函数)

具体语法如下:

构造函数:类型(){

}

析构函数:~类型(){

}

其中构造函数可以分为有参数和为无参数类型;即无参构造和有参构造

按照类型分可以分为普通构造和拷贝构造

拷贝函数调用时机

1.使用一个以及创建好的对象来初始化一个对象

例如:

Person p1 (10);//有参构造

Person p2 (p1);//拷贝构造//此时p2与p1一样;相当于拷贝了一个相同的对象

2.值传递的方式给函数参数传值

void  work1(person p){

//此时对形参的改变不影响实参,相当于给实参p拷贝了一个副本传入函数中;

调用了拷贝函数;

}

3.以值方式返回局部变量

例如:

在一个函数类型为person类中,申请了一个局部对象p1,当返回p1时,编译器会自动调用拷贝函数,拷贝一个p1的副本作为返回值传回,此时p1已经被释放;

Person  work1(){

Person p1;

Return p1;

}

如何调用 拷贝构造 有参数构造
  1. 小括号法

例如定义了一个 person类别

在调用其中 的 有参  拷贝 函数时:

Person p1 (10);//有参构造

Person p2 (p1);//拷贝构造

  1. 显示法:

Person p1=person(1);//调用有参构造  //相当于给匿名对象取了个名字p1 和p2

Person p2 =person(p1);//调用拷贝构造;

  1. 隐式转换法:

Person p1=1;//相当于写了person p1=person(1); 调用有参构造

Person p2=p1;//拷贝构造;

普通构造和拷贝构造语法区别:

拷贝构造相当于复制了一份对象,将该对象与原对象属性进行复制,且传入的对象不能改变;并且以引用的方式传入;

类型(const 类型 &p ){}

在定义一个类时至少要有三个函数,分别是构造函数 析构函数 拷贝函数;若不写 系统自动初始化这些函数类型

若已经写了有参构造函数,系统不会提供无参函数,会提供拷贝函数

若写了拷贝函数,系统将不会提供任何函数,需要自己实现

深拷贝与浅拷贝

 浅拷贝为编译器为我们自己实现的拷贝构造函数,主要实现对传进的对象进行复制各个属性;

 深拷贝为我们自己对拷贝构造函数进行改变,让他在堆区重新创建一个内存空间用于存储对象的属性;

在堆区开辟的内存空间需要在析构函数中释放操作;

主要问题:

当我们在堆区开辟一个内存存储属性时,若利用编译器为我们提供的浅拷贝,当我们申请了p1对象,并且通过p1拷贝了出了p2时,当我们要释放在堆区开放的内存时,在析构函数中释放堆区内存,在释放p1和p2两个对象中的堆区内存时,会造成重复释放问题,导致系统崩溃;因此我们需要采用深拷贝,让拷贝构造函数自己在堆区开辟内存,存放属性,释放内存时,各自释放各自的,不会发生重复释放问题;

具体代码:

Class solution{

//有参构造函数

Solution(int age,int height)

{

m_height=New int(height);//在堆区申请一块存放height内存,返回地址

m_age=age;

}

~Solution()//析构函数

{

//释放堆区的内存

If(m_height!=null)

Delet m_height;

m_height=null;

}

//深拷贝构造函数

Solution(const solution &p)

{

m_age=p.m_age;

m_height=New int(*p.m_height);//重新申请一块新的存放相同数据的堆区内存

 //m_height=p.m_height//浅拷贝默认提供的直接复制

}

Public:

Int m_age;//对象属性

Int *m_height;//用于存放堆区申请内存的地址

};

总结:如果属性有在堆区开辟的,一定要自己提供拷贝构造函数,防止浅拷贝带来的问题

初始化对象

通过构造函数来实现对属性的初始化,即赋值操作:

传统的方式是构造有参构造函数,让其传入参数,在函数体中再去给属性赋值;

还有一种新方式,直接再构造函数小括号后面()加上:和属性对应的初值;最后跟上{}

例如:(已经定义了两个对象前提)(该对象为private类型 只能在类中访问)

//传统意义:

Person (int a,int b)

{

Age=a;

Height=b;

}

//初始化对象

Person ():age(10),height(180)

{

}

或是

Person (int a , int b):age(a),height(b)

{

}

在主函数中定义一个对象时:

Person p1(10 ,180)//第二种方式直接赋值初始化

Person p1;//第一种方式 已经初始化值了

类对象作为类成员

在一个类中成员为其他类对象时我们称该成员为对象成员:

当其他对象作为本类成员,构造函数先构造类对象,在构造自己;

析构的顺序与构造相反;类对象后析构;

例如:

#include<iostream>

using namespace std;

class phone{

public:

//构造函数

phone(string phone){

m_phone=phone;

cout<<"Phone的构造函数"<<endl;

}

//析构函数

~phone(){

cout<<"phone的析构函数"<<endl;

}

public:

string m_phone;

};

class people{

public:

//构造函数

people(string name,string phonename):m_name(name),my_phone(phonename)

{

cout<<"people 的构造函数"<<endl;

}

//析构函数

~people(){

cout<<"people的析构函数"<<endl;

}

public:

string m_name;

phone my_phone;

};

void test01(){

people p1("yupuning","iphone 11");

cout<<p1.m_name<<"的"<<p1.my_phone.m_phone<<endl;

}

int main(){

test01();

system("pause");

return 0;

}

静态成员//位于全局作用域上 不属于类对象

静态成员对象 

1.所有对象共享一份数据;//数据值相同,

2.编译阶段分配内存;

3.类内声明;类外初始化(在括号外给静态成员对象赋值)

静态变量不属于任何一个对象,所有对象都共享同一份数据;因此静态成员有两种访问方式:

1.通过对象访问

2.通过类名访问

静态成员变量也是有访问权限的,若为private,则内外无法访问;

#include<iostream>

using namespace std;

class people{

public:

//构造函数

people()

{

cout<<"people 的构造函数"<<endl;

}

//析构函数

~people(){

cout<<"people的析构函数"<<endl;

}

public:

                   static string m_name;

string my_phone;

};

string people::m_name="YUpuning";//类外初始化;

void test01(){

//通过对象访问

people p1;

cout<<p1.m_name<<endl;

//通过类名访问

cout<<people::m_name<<endl;

}

void test02(){

people p1;

cout<<p1.m_name<<endl;

p1.m_name="yupuning";

people p2;//p1改变了静态成员,p2的也跟着改变

cout<<p2.m_name<<endl;

}

静态成员函数

1.所有对象共享同一个函数

2.静态成员函数只能访问静态成员变量

静态函数不属于任何一个对象,所有对象都共享同一份数据;因此静态函数有两种访问方式:

1.通过对象访问

2.通过类名访问

静态函数可以访问静态成员变量,由于静态变量是共享的;不能访问非静态成员变量;无法区分到底是那个对象的成员;

静态成员函数也是有访问权限的;

class people{

public:

//构造函数

people()

{

cout<<"people 的构造函数"<<endl;

}

//静态函数

static void func(string name){

m_name=name;

}

//析构函数

~people(){

cout<<"people的析构函数"<<endl;

}

public:

           static string m_name;

string my_phone;

};

成员变量 和成员函数 分开存储

空对象占用内存为1;c++编译器会给每个空对象分配一个字节空间,是为了区分空对象占内存位置;意思就是给该空对象给了一个地址,这样就可以对其处理和找到;

非静态成员函数不属于类对象上;

静态成员变量不属于类对象上;

静态函数不属于类对象上;

只有非静态成员变量属于对象上;

This 指针:this指针指向被调用的成员函数所属对象

this指针的本质为指针常量  指向是不能改变的  但是指向的对象的内容可以改变

1.解决名称冲突(形参和成员名重名)

class people{

public:

//构造函数

people(string my_phone)

{

This->my_phone=my_phone;   //this指向该属性的对象this->表示对象中成员

cout<<"people 的构造函数"<<endl;

}

//静态函数

static void func(string name){

m_name=name;

}

//析构函数

~people(){

cout<<"people的析i构函数"<<endl;

}

public:

           static string m_name;

string my_phone;

};

2.返回对象本身;*this;

Person &personaddage(person& p) //以引用的方式传入其本体,若不用引入,则会拷贝一个新的函数返回

This->age+=p.age;//this指向调用该函数的对象

Return *this;//返回调用该函数的对象本体

}

链式编程思想:无限调用函数;

Person p2(10);

P2.personaddage.personaddage.personaddage;//调用之后返回其p2本体;

空指针调用函数调用成员函数

利用一个空指针去调用类中的成员函数时,要注意传入的指针为空类型;成员函数中若有成员变量时;

将会发生报错,因为this指针为空类型,无法找到成员变量;

class people{

public:

//构造函数

people()

{

cout<<"people 的构造函数"<<endl;

}

//成员函数

 void func(string name){

         if(this==NULL)

         return;

cout<<name;

}

//析构函数

~people(){

cout<<"people的析构函数"<<endl;

}

public:

                    string m_name;

string my_phone;

};

void test05(){

people *p=NULL;//空指针 类型为people

p->func("yupuning");//调用成员函数的成员变量时要注意指针不能为空

}

const修饰成员函数

常函数与常对象

常函数:

  1. 不能修改成员属性

当成员函数被const修饰时 ,即在成员函数后面加上const,修饰的this的指向,this指针指向的对象的值不能改变;若想修改改变变量的值,在成员变量前面加上关键字mutable;

常对象:

  1. 常对象只能调用常函数

在对象前加上const;变为常对象;与常函数相同,其成员的值不能被改变,若成员属性前加上了mutable则可改变;

常对象只能调用常函数(由于常对象的属性不能被改变,若调用其他成员函数可能会改变其成员的属性)

常对象不能调用普通的成员函数 ;

友元

友元概念:让一个函数或者类访问访问另一个类中的私有成员

全局函数做友元:

全家函数要访问私有属性时,在函数前加上friend 放在类中即可实现,该函数访问私有成员

类作友元:

让该类可以访问其它类中的私有属性;在类名前加上friend放在要访问的类中;

在类外也可以写成员函数;只需加一个作用域即可;还需要加上返回值类型;

成员函数作友元:

让成员函数可以访问该类中的私有属性;

在其前面加上friend 以及作用于哪个类下的类名;

运算符重载

加号运算符重载:

对已有类型进行重新定义,赋予其另外一种功能,以适应不同的数据类型

成员函数 实现加号运算符重载

Person Operator +(person &a)

{

Person temp;

实现类中对象相加赋值给temp;

Return temp;

}

全局函数实现加号运算符重载

Person Operator +(person &a,person&b)

{

Person temp;

实现类中对象相加赋值给temp;

Return temp;

}

此时就可以实现person p3=p1+p2;

成员函数重载加号本质为person p3=p1.operator+(p2);

全局函数重载加号本质为person p3=operator+(p2,p1);

两个类的相加;

函数运算符重载版本:

(实现person+int型)

Person Operator +(person &a,int num)

{

Person temp;

实现类中对象相加赋值给temp;

Return temp;

}

内置数据类型的表达式不能发生重载

不能滥用 运算符重载 加法写成减法或乘法,无法分辨

左移运算符重载

实现 输出自定义内容

只能利用全局函数重载左移运算符

Ostream & operator<<(ostream &cout,person& p)    本质为operator <<(cout,p);

{

Cout<<p中的成员变量;

Return cout;

}

简化为;

Cout<<p<<endl;(并且可以无限追加,实现链式编程,因为一直返回cout)

#include<iostream>

using namespace std;

class person{

friend ostream & operator<<(ostream &cout,person &p);

public:

int age;

private:

int birth;

public:

//成员函数实现重载

person operator+(person &p)

{

person temp(0,9);

temp.age=this->age+p.age;

temp.birth=this->birth+p.birth;

return temp;

}

person(int age,int birth){

this->age=age;

this->birth=birth;

cout<<"person的构造函数"<<endl;

}

};

//全局函数重载加号

/*person operator+(person &p1,person &p2)

{

person temp(0);

temp.age=p1.age+p2.age;

return temp;

}*/

//全局函数 实现重载<<

ostream & operator<<(ostream &cout,person &p)

{

cout<<"age="<<p.age;                  

cout<<"birth="<<p.birth;

return cout;

}

void test01()

{

person p1(10,10);

person p2(10,10);

person p3=p1+p2;

cout<<p3<<endl;

}

int main()

{

test01();

system("pause");

return 0;

}

重载++运算符

实现对象成员变量的自增;

class my{

friend ostream & operator<<(ostream &cout,my &p);

public:

my(int a){

this->a=a;        

}

        //重置前置加号

my & operator++()

{

this->a++;

return *this;        

}

//重置后置++

my & operator++(int )

{

my temp=*this;

this->a++;

return temp;

 }

private:

int a;

};

赋值运算符重载

编译器提供浅拷贝,对于开辟在堆区的数据,容易造成重复释放;

故我们应该自己提供一个赋值运算符重载,让其赋值的对象重新深拷贝;

来实现赋值操作

person &operator=(person &p){   

//判断该指针是否为空

if(age!=NULL){

//如果不为空 则先释放 再重新申请一块内存

delete age;

 age=NULL;

}

age=new int (*p.age) ;

return *this;

}

函数调用运算符重载  仿函数

非常灵活

通过在类中重载小括号实现实例化对象后直接调用函数;

可以实现多个功能

继承

类与类之间存在的特殊关系;除了他有自己的特性外还有共性;通过继承可以减少代码复杂;

在公共的特点上可以利用继承的技术,将其先放在一个类中;在其他类中去进行继承;

Class 子类(派生类) :继承方式 父类(基类)

{};

继承方式

  1. 公共继承

父类中的公共权限均可访问,私有权限子类无法访问与保护权限子类内可访问类外不可访问,访问类型不变为原类型

  1. 保护继承

父亲中公共权限均可访问,访问类型变为protected权限,私有权限不变化;保护继承变为保护权限,类外访问不到

  1. 私有继承

私有继承子类类外不可访问,变为私有权限;父类中私有成员子类类外不可访问;其余可以在类内访问;

变为私有权限后,再将其作为父类时,无法访问其成员变量;

继承中的对象模型

父类中的所有非静态成员都会被子类继承下去;

父类中的私有属性被隐藏,因此访问不到,但是确实被继承下去了。

继承构造和析构的顺序

先构造父类在构造子类;

析构时先析构子类在析构父类;

继承中的同名成员处理

直接访问该名为子类中的成员变量;

若要访问父类中的成员,需要加上作用域 base::变量名

如果访问同名的函数:

与成员变量相同 ,加上作用域即可;

如果子类中出现与父类相同的函数名,编译器会自动省略父类中相同的函数名;

若要访问该省略的函数,需要加上作用域;

静态同名情况下也是相同,但是作用在全局上,可以直接通过访问类名来调用函数或者成员;

也可以通过对象和作用域来访问;

多继承语法(一个类继承多个类)

若出现同名情况 加上作用域以区分

菱形继承

当菱形继承的时候,两个父类拥有相同的的数据,需要加以作用域以区分;

利用虚继承可以解决浪费问题;在继承之前加上关键字virtual变为虚继承;变为虚基类。

vbptr为虚基类指针,偏移的位置均为相同的地址,让数据只有一份

多态

内置数据类型的表达式不能发生重载

不能滥用 运算符重载 加法写成减法或乘法,无法分辨

标签:p1,函数,对象,成员,扩展,c++,int,内容,cout
From: https://blog.csdn.net/2302_80554221/article/details/143769266

相关文章

  • STL标准模板库c++
    STL:广义上分为:容器,算法,迭代器容器与算法间通过迭代器进行无缝连接。STL六大组件,分别是容器,算法,迭代器,仿函数,适配器,空间配置器。vector容器可以理解为数组;为单端数组,区别在于数组为静态空间,而vector可以动态扩展动态扩展:不是在原空间下,找到更......
  • 单向链表题库2(c++)
    目录前言[1.力扣——LCR123.图书整理I](https://leetcode.cn/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/description/)[2.力扣——LCR024.反转链表](https://leetcode.cn/problems/UHnkqh/submissions/580256040/)[3.力扣LCR141.训练计划III](https://le......
  • 开源 - Ideal库 - 常用枚举扩展方法(二)cD
    合集-Ideal库-Common库(6)1.开源-Ideal库-常用时间转换扩展方法(一)11-072.开源-Ideal库-常用时间转换扩展方法(二)11-093.开源-Ideal库-获取特殊时间扩展方法(三)11-11:westworld加速4.开源-Ideal库-获取特殊时间扩展方法(四)11-125.开源-Ideal库-常用枚举扩展方......
  • 开源 - Ideal库 - 常用枚举扩展方法
    开源-Ideal库-常用枚举扩展方法(一)合集-Ideal库-Common库(6) 1.开源-Ideal库-常用时间转换扩展方法(一)11-072.开源-Ideal库-常用时间转换扩展方法(二)11-093.开源-Ideal库-获取特殊时间扩展方法(三)11-114.开源-Ideal库-获取特殊时间扩展方法(四)11-125.开......
  • c++ 标准 智能指针 与 qt 智能指针 对比
    C++标准库提供了std::unique_ptr和std::shared_ptr等智能指针,而Qt则提供了QScopedPointer、QSharedPointer和QWeakPointer等自己的智能指针。两者在设计上有一些相似之处,但也存在一些关键的差异。下面是C++标准智能指针和Qt智能指针的详细对比:1.std::uniq......
  • C++生成随机数
    目录一、传统方式:std::rand 和 std::srand使用方法:优缺点:二、现代方式: 库(推荐)1. 随机整数2. 随机浮点数3. 布尔值4. 字符5. 正态分布(高斯分布)6. 离散分布的随机数7. 随机字符串8. UUID(通用唯一标识符)三、std::shuffle:用于打乱序列四、总结:选择合适的......
  • 关闭 Windows 中的各种广告和提示信息,你可以通过修改注册表(.reg 文件)来实现。这些设置
    关闭Windows中的各种广告和提示信息,你可以通过修改注册表(.reg文件)来实现。这些设置可以帮助你屏蔽掉一些烦人的广告和推荐内容。以下是可以通过.reg文件关闭的功能的注册表条目。1. 关闭文件管理器广告文件资源管理器中的广告(如OneDrive提示或其他推荐内容)可以通过以下......
  • 【华为OD机试真题E卷】573、区间交叠问题 | 机试真题+思路参考+代码解析(E卷复用)(C++、J
    文章目录一、题目......
  • Linux-vscode-c++-slambook2-库文件找不到路径
    Linux-vscode-c++-slambook2-库文件找不到路径分享所遇到的困难,填补这些坑洞,希望后来者能够如履平地。首先已经在c_cpp_properties.json中已经添加了相关的文件,"includePath":["${workspaceFolder}/**","/usr/include/eigen3"......
  • Unity实现一个简单的在线翻译功能,编辑器扩展和运行时
    前言在Unity项目开发过程中,经常需要处理多语言文本。本文将介绍如何实现一个简单实用的在线翻译功能,通过调用Google翻译API,帮助开发者快速完成文本翻译工作。既可以在编辑器中使用,也可以在运行时调用,满足不同场景的翻译需求。一、效果演示(编辑器扩展)TranslateTest......