c++小结

面向对象程序设计
OOP(Object Oriented Programming)

int s1=1;
double s2=2.5;
char s3=‘g’ , s4=‘j’;
等价于
int s1(1);
double s2(2.5);
char s3(‘g’), s4(‘j’);

#include<string>

定义:


string类成员函数:

str.length()str.size()是string类对象的成员函数
strlen(str) 求字符数组的长度
三者均不包含’/0’!

string类操作符:

getline(cin, str);

换行符分割,空格当做符号

string类串 位置指针:

位置指针=迭代器 iterator
访问相应位置字符,可向前向后访问
不检查是否越界

常指针,仅读取,不能修改对象字符

string类 的串结尾不是’/0’
c串以NULL结尾
NULL、’/0’的数值都是0
'0’的数值是48!
https://blog.csdn.net/m0_37592397/article/details/79701992

string类串和c串:

wchar_t为解决char256范围小的问题而提出

常量:文字常量,符号常量,常变量
常变量const 定义时一定要赋初值


逗号运算,

x=(a,b,c);
abc依次运算,c的值给x


内联函数inline:

空间换时间
调用函数变为顺序执行,跳转的时间没有了,程序执行更快
它不是被调用,而是编译器会扩展源代码,将内联函数代码复制到调用区域,这样是形式上调用,实际上顺序执行

内联函数:
不能有循环体
递归不能是内联
不能有swtich


形参默认值

从右向左依次默认定义,有右边的形参无默认值,则其左边就不能默认赋值

int max(int a, int b=1)int max(int a=1, int b=1)int max(int a=1, int b)×
int max(int a, int b=min(40, 5))

声明时默认形参值,定义时可不默认形参值
调用函数时,其实参值权限>默认形参值


动态分配:

库函数:malloc、calloc、free
c++运算符:new、detele(效率高)

typedef struct LNode
{
	int data;
	struct LNode *next;
}*Link,LNode;

LNode *q,*p=L;
q = (LNode *)malloc(sizeof(LNode));
q = (LNode *)calloc(1, sizeof(LNode));

数组:
(int*)malloc(n * sizeof(int));
(int*)calloc(n, sizeof(int));

void *calloc(int n, int size);
内存的动态存储区中分配n个长度为size的连续空间,函数返回一个指向分配起始地址的指针;如果分配不成功,返回NULL

malloc不初始化,分配到的空间中的数据是随机数据
calloc在动态分配完内存后,自动初始化该内存空间为零,用完后free(q)对内存进行释放,不然内存申请过多会影响计算机的性能,以至于得重启电脑

持久化分配空间

int *p=new int(5);
等价与
int *p;
p=new int(5);
指针p指向初值为5int对象
int *p=new int[5];
等价与
int *p;
p=new int[5];
指针p指向5个未初始化的int对象的首地址,不能定义时赋初值
即:p就是数组首地址

new失败会返回NULL
子函数内部定义的数组,子函数想返回这个数组的首地址
若普通定义,如 int a[5];它是局部变量,子函数调用完会释放局部变量!
这样定义可解决这个问题:
int *a = new int[5];
new是分配的持久内存空间

一般数组int a[这里不能是变量!];

int size=5;
int *a = new int[size];  size是变量,属于动态分配内存(堆区)

detele p; 撤销指针p,针对变量
detele[] p; 撤销数组空间,p是指针

new后记得detele!

Clock *c1= new Clock[5];
detele[] c1;

建立m*n动态二维数组

int **dm;
dm= new int*[m];
for(i=0; i<m; i++)
{
   if( (dm[i]=new int[n])==NULL )
      exit(0);
}
。。。
for(i=0; i<m; i++)
{
   detele[] dm[i];
}
detele dm;

注意:detele的顺序和new的顺序相反

动态数组容量不够解决办法:
重新分配够用的空间b
原数组内容a复制到b
释放a的空间


对象:

是事物的抽象,
是属性、操作、方法的封装体
静态特征:可用数据描述的特征
动态特征:对象表现的行为或具有的功能
属性:描述静态特征的数据项
服务:描述动态特征的操作序列

对象间的通信:消息

消息的实现:函数调用、程序内部通信、各种事件的发生和响应

事件:系统事件、用户事件

系统事件:由系统激发,
如:时间每隔24小时,银行储户的存款日期增加一天

用户事件:由用户激发,
如:用户点击按钮,在文本框中显示特定的文本

对象有生命周期:
出生,生长,灭亡
创建(分配存储空间),
活动(自主运行,接收消息并处理),
删除(其存储空间设为无效并回收)


类:

是抽象,同一类对象的共同属性(静态特征)、行为(方法,动态特征)
即:有相同属性、方法的对象的抽象
类=属性+方法
属性:名字,类型,可修改型,可见性
方法:函数
类通过外部接口与外部发生关系

对象是类的具体实例
一个类的不同对象:
相同点:属性、方法
不同点:对象名、属性值

面向对象的基本特征:

封装,继承,多态

封装:
对象属性、方法的可见性(公有、私有)

继承:
子类 = 派生类
父类 = 基类 = 一般类
子类有父类的所有属性、方法

函数重载 函数覆盖=函数重写 多态

函数重载
函数名一样,参数不同
int max(int,int,int b=1)和
int max(int,int)会导致二义性
解决办法:增加或减少实参个数
同一范围中,函数名一样,但是函数的形式参数(参数的个数、类型、顺序)必须至少一个不同
即:同一个函数完成不同的功能,自然函数体细节实现不同

函数覆盖 = 函数重写:
父类与子类之间,
函数名、参数类型、返回值类型和父类对应函数必须严格一致(只有一种情况下返回值可以不一致:返回自己类的引用或者指针的时候)
也就是只有函数体不同
当子类对象调用该函数,会自动调用子类中的版本,而不是父类的版本

多态:
不同数据类型的实体提供统一的接口
人话:
父类有个虚函数,不同子类继承父类,要实现这个虚函数,不同之类实现该函数的细节和结果不同,这个不同就是多态(不同对象有不同的反应)
如:
父类是动物,有方法 [叫]
子类是猫和狗
猫的叫是[喵]
狗的叫是[汪]

多态,作用域不同
函数重载,作用域相同


封装

类和对象:

类:包含函数的结构体
是一个数据类型
类的数据成员不占空间,所以不能赋初值,可以用构造函数赋初值
类的数据成员不能是自己类型的变量

结尾;

类的成员函数:
放在类中定义就是内联的inline

也可以类中声明,类外定义
void clock::max(int a, int b){}


private的数据成员,在类外无法访问
可通过public的成员函数来访问,并赋值

构造函数,对象的初始化赋值
析构函数,清理工作

结构体对象初始化

结构体名 具体对象名(值1, 值2, 。。。。)

类对象初始化,有构造函数的话,就可以像结构体对象那样初始化
c++默认帮你生成一个构造函数,即使你没写,这个默认构造函数是空的!
自定义后,以自定义为准,默认构造函数就不存在了
法一:类名 对象名(值1,。。)
Clock my1(1, 2);(结构体可直接这样初始化)
法二:类名 对象名= 类名(值1,。。。)
Clock my1=Clock(1, 2);

构造函数:

必须是public
不写返回值类型,写void也不行
必须与类名一样
可重载
建立对象时系统自动调用
动态申请内存

析构函数:

对象消失时,释放析构函数申请的内存
有默认的析构,但它啥事也不做!
一般要自定义

形式:
~类名();
类名=构造函数名

必须是public
可以是虚函数
不写返回值类型,写void也不行
无参
只能有一个析构函数,不能重载

析构函数的清理语句完成对象的消失

~String()
{
	if(Str!=NULL)
	{
		detele[] Str;
		Str=NULL;	
	}
}

构造函数用的时候是对象的初始化建立,属于局部变量,放在栈中
一个类的多个对象创建,构造函数的调用顺序=创建顺序
析构函数的调用是创建顺序的相反

拷贝构造函数 = 克隆

以现存对象为新对象的初值
c++默认帮你构造一个拷贝构造函数
也可以自定义:

Clock(Clock &c)
{
	xx=c.xx;
	。。。
}

触发拷贝构造函数的条件:
1 一个已存在的类对象初始化另一个新建的类对象
Clock c1(1,2,3);
Clock c2(c1);
2 函数形参是类对象,已存在的对象作为实参传给形参
3 函数返回值是类对象

Clock(1,2,3);不是已存在对象(变量),它是常量!

对象指针和对象引用不触发构造函数,因为他们没有建立新的对象

浅拷贝 深拷贝:

默认拷贝是浅拷贝,即已存在对象和新对象的拷贝是成员值赋值,它没有给新对象分配内存资源
若是指针,两对象的指针指向同一个内存地址,两对象的析构函数调用时,前一个析构已经释放这个内存了,后一个析构就会出现问题!
深拷贝就是解决这个问题的:

String(String &s)
{
	len=s.len;
	if(len!=0)
	{
		Str=new char[len+1];
		Strcpy(Str, s.Str);
	}
}

c++默认帮你生成一个拷贝构造函数,即使你没写,自定义后,以自定义为准,默认拷贝构造函数就不存在了

对象指针:

Clock c1(8,0,0);
Clock *p1=&c1, p2;
p2=&c2;
p1->。。。
(*p1).。。。

函数参数用对象指针 而不是对象的好处:
1 对形参的改变影响着实参
2 传递的是地址,缩小时空开销效率更高

对象引用:
类似引用
对象是变量,类是数据类型
数据类型不存在引用,故 类引用不存在
Clock &c2=c1;

对象引用

同类型
定义必须初始化(函数参数 函数返回值的引用不需要初始化)
是别名,不新分配内存

this指针:

类中有private变量a
只能本类的成员函数给a赋值,若形参也叫a
this->a=a;
(*this).a=a;
this指针 是指针常量
this不是对象的别名,而是指向 调用对象的指针

组合类:

构造函数形式:
类名(形参表): 成员对象1(子形参表1),成员对象2(子形参表2),。。{}
Clock(int a,int b,int c): newClock1(a,b), newClock2(b,c){}

调用形式:
类名 对象名(实参表);
Clock c(1,2,3);

静态成员static:

是类的属性,类的不同对象,其静态成员一样
其被访问权限和一般成员一样
静态:存储空间独立分配,
静态:数据成员、函数成员

静态数据成员
定义类后,对象创建前就存在了
类内声明,内外定义
类内声明:static int a;
内外定义 int A::a=1; (无static!)

静态函数成员
定义类后,对象创建前就存在了

类内声明,内外定义
类内声明:static int max(。。);
内外定义 int max(。。。) {} (无static!)

或直接类中声明定义

调用:
类名::静态函数名(。。。);

常对象 常成员:

int const 对象名;
const int 对象名;等价的

常对象仅被类的常成员函数访问!它不能被修改
常对象仅可访问它的常成员函数,这是常对象唯一的对外接口方式
一般对象可以访问常成员函数
常对象定义就要初始化,用的是构造函数初始化

常成员函数:
声明
int max(。。)const;
实现:
int max(。。)const{}const不能丢!
常成员函数不能更新对象的数据成员(可以是常对象的,也可不是;数据成员可const,也可非const),
常成员函数不能调用一般成员函数

常成员函数重载

声明:
原函数:
int max(。。){}
常成员函数重载:
int max(。。) const{}
一般对象名.max
常对象名.max
不加const,两个函数同名 但两者没有关系

这就是重载了

常数据成员仅通过构造函数初始化列表进定义:
int const a;
const int a;
初始化:
A(int i): a(i){}

友元函数

对于类的private成员(属性 数据 、 方法 函数)
只有类的成员函数可以访问
若private成员很多
在类外,可能有很多种访问private成员的组合可能
对每种可能都写一个成员函数不现实
把private改为public,则失去c++封装隐蔽的优点(这时候优点变缺点)
用友元函数!

友元:
不属于类的成元
可以访问类的所有成员
可以是另一个类的成员,也可不是,
可以是不属于任何类的一般函数
可以是一个整类

友元函数定义:
friend int max(。。){}
可在类中声明在内外定义,内外定义不可指定该友元函数是属于哪个类(因为友元不属于任何类)
声明加friend,内外定义不用加friend,即不能对象名.友元函数名(实参)

友元类定义:
friend class A{}

两个友元类相互引用:

class B
class A{friend class B。。。}
class B{friend class A。。。}

继承、派生:

子类 = 派生类
父类 = 基类 = 一般类
子类有父类的所有属性、方法
类层次:父类、子类的这种关系

继承:子类有父类的所有属性和方法(变量和函数)
单继承:子类只有1个父类
多继承:子类有2个以上的父类

多层继承:子类b继承于类a,子类b又是类c的父类(单继承、多继承都可以有多层继承)

继承方式:

public 公有
protect 保护
private 私有(默认继承方式)


private成员被子类继承了,子类也无法访问该成员
对于protect成员,子类的成员函数可访问,子类对象不能访问

class b: public a, private c{}

子类继承后可以有的操作:
1 继承数据成员和函数成员
2 改造父类成员,对函数成员的改造叫覆盖
3 添加新成员

函数重载:
同一范围中,函数名一样,但是函数的形式参数(参数的个数、类型、顺序)必须至少一个不同
即:同一个函数完成不同的功能,自然函数体细节实现不同

函数覆盖 = 函数重写:
父类与子类之间,
函数名、参数类型、返回值类型和父类对应函数必须严格一致(只有一种情况下返回值可以不一致:返回自己类的引用或者指针的时候)
也就是只有函数体不同
当子类对象调用该函数,会自动调用子类中的版本,而不是父类的版本

继承不可以循环
即父类和子类不能相互继承

继承与组合类
继承:一般与特殊
组合:整体和部分

子类的构造函数与析构函数

多继承构造函数形式:

class b(参数总表): 
父类a1(参数表1), 父类a2(参数表2)。。。,
成员对象1(参数1),。。。
{}

父类的构造函数有参数,子类构造函数就要提供对应的初值,反之可以不提供

子类构造函数就要提供对应的父类初值的原因:子类对象创建,出发触发父类构造函数,这得有初值呀,不然报错

父类构造函数触发调用的顺序是:子类继承时的从左往右的顺序,与之类构造函数初始化列表的顺序无关的顺序
class b: public a, private c{}
构造函数触发顺序:先a后c

父类析构函数触发调用的顺序是:调用顺序的相反(就栈进栈出的顺序呗)

二义性问题:
父类a1、a2有同名成员函数max(变量也一样)
子类b继承了a1、a2
b类内调用max(),程序如何知道这是谁的max()?
解决办法:
成员函数名限定:a1::max();
成员函数重定义(或许是覆盖,或许函数重载)

这个办法依然有问题:
例子:
a
b c
d
class a有数据i
class b继承a,i=5
class c继承a,i=9
clasa d继承b、c
d对象调用i,i是几?

不同途径继承同名数据成员,造成终子类的数据不一致问题
解决办法:虚基类

虚基类:

在继承时用到
形式:

class b: virtual public a, public c{}
class d: virtual public a, public e{}

a是b和d的虚基类,c不是b的虚基类,e不是d的虚基类
a是虚基类,它的成员在被继承时,在系统中只有一份拷贝

虚基类的构造函数有参数,其所有子类,子类的子类 的构造函数都要给其参数:

虚基类a构造函数
a(int b){}
子类a1构造函数:
a1(int i):a(i){}
子类a2构造函数:
a2(int j):a(j){}
最远派生类构造函数a12
a12(int i, int j, int k):a(i),a1(j),a2(k){}

虚基类构造函数触发调用:
只有最远派生类创建对象时,只调用虚基类的构造函数,中间的类不调用其构造函数,保证虚基类的成员只初始化一次

虚基类调用构造函数的顺序:
(1)虚基类的构造函数在非虚基类之前调用;
(2)同一层次中包含多个虚基类,其构造函数按说明的次序调用;
(3)若虚基类由非虚基类派生而来,仍先调用基类构造函数,再调用派生类的构造函数。

类型兼容:

子类对象可作为父类对象使用
1
子类对象可赋值给父类对象
父类对象名=子类对象名拷贝构造函数
2
子类对象可初始化父类引用
父类 &父类对象名=子类对象名;
3
子类对象地址可初始化指向父类的指针
父类 *父类对象名=&子类对象名;

多态:

函数重载 函数覆盖 多态

函数重载
函数名一样,参数不同
int max(int,int,int b=1)int max(int,int)
int max(1,1)这种调动会导致二义性
解决办法:增加或减少实参个数
同一范围中,函数名一样,但是函数的形式参数(参数的个数、类型、顺序)必须至少一个不同
即:同一个函数完成不同的功能,自然函数体细节实现不同

函数覆盖 = 函数重写:
父类与子类之间,
函数名、参数类型、返回值类型和父类对应函数必须严格一致(只有一种情况下返回值可以不一致:返回自己类的引用或者指针的时候)
也就是只有函数体不同
当子类对象调用该函数,会自动调用子类中的版本,而不是父类的版本

多态:
同样的信息被不同类型对象接受,有不同的行为(函数不同)
人话:
父类有个虚函数,不同子类继承父类,要实现这个虚函数,不同之类实现该函数的细节和结果不同,这个不同就是多态(不同对象有不同的反应)
如:
父类是动物,有方法 [叫]
子类是猫和狗
猫的叫是[喵]
狗的叫是[汪]

多态,作用域不同
函数重载,作用域相同

多态:
编译多态,运行多态

编译多态:编译时,确定同名操作的具体对象
运行多态:运行时,动态确定操作针对的具体对象

联编:确定具体对象的过程
静态联编,动态联编

静态联编:编译、连接时进行(函数重载,函数模板)
动态联编:运行时

运算符重载

只有5个运算符不能被重载:

. 选择运算符
.*  指针运算符
:: 作用域分辨符
?: 三目运算符
sizeof 数据大小运算符

一元运算符: T obj → operator T(obj)
!a → operator !(a)
二元运算符:obj1 T obj2 → operator T(obj1,obj2)
1 + 2 → operator +(1,2)
前置++前置-- 遵循一元运算符规则
后置++后置--obj T → operator T(obj,0)
a ++ → operator ++(a,0)

运算符重载规则:
只针对已存在的运算符
不改变原有语义、优先级、参数个数
改变的参数(形参、实参)的数据类型

operator + (8,9);
operator + (8.0,9.0);

其函数原型:
int operator + (int ,int);
double operator + (double ,double);

运算符重载为为类的友元函数
这样可访问类的所有数据成员!

friend int operator +(形参表)
{。。。}

运算符重载为类的成员函数

int 类名::operator +(形参表) 此时声明在类内,定义在类外
{。。。}

此时形参表会少写一个参数
如二目运算,有两个参数,即两个对象a1、a2
因为此时是类的成员函数,对象a1可调用运算符
运算法的参数写对象a2

形式:

类名
{
	。。。
	类名 operator +(类名 对象名);
	Clock operator +(Clock B);
}

Clock Clock::operator +(Clock B)
{
	return。。。
}

main中调用:
{
	Clock A(。。。),B(。。。),C;
	C=A+B;
	。。。
}
1:
Clock D(。。。);
return D;

2return Clock(。。。);

1效率低
2是常量,效率高

运算符重载为类成员函数:
单目运算(一元运算)
=、()、[]、->
涉及修改对象的状态
类型转换函数(一定不能是友元函数)

运算符重载为友元函数:
二元运算,但=、()、[]、->这些二元运算不行((int)i对应显式类型转换)
隐式类型转换
运算符有可交换性
A+B左右是类对象

显式类型转换:

float i= 5.5int j = (int)i;

隐式类型转换:

int i= 5.5float j = i;

运算符=重载为成员函数
=不重载就是浅拷贝
重载的目的在于深拷贝

运算符[]重载为成员函数:

class Clock
{
private:
	char *Str;
	int len;
public:
	Clock & operator [] (int n)
	{
		return *(Str+n);
	}
}

运算符->重载为成员函数:
可防止指针指向NULL!防止野指针!

class myClock
{
private:
	Clock *p; 注意本类是类Clock的子类
public:
	Clock * operator ->
	{
		static Clock a(实参);
		if(p==NULL)
			return &a;
		return p;
	}
}

()运算符重载为成员函数:
()成为函数调用运算符

class Add
{
	double operator()(double a, double b)
	{retern a+b;}
}

Add的实例对象就是函数对象

虚函数

多态:
编译多态,运行多态

编译多态:编译时,确定同名操作的具体对象
运行多态:运行时,动态确定操作针对的具体对象

联编:确定具体对象的过程
静态联编,动态联编

静态联编:编译、连接时进行(函数重载,函数模板)
动态联编:运行时

静态联编:

父类 Clock
子类 Clock_asd
Clock *p,q=Clock(。。。);
Clock_asd r=Clock_asd(。。。),&k=q;

p=&r; 静态联编
&k=q; 静态联编
p->函数名;调用的是父类的函数,但实际上我们想用子类的函数

用虚函数解决这个问题!
这对应动态联编
virtual 函数类型 函数名(形参表){}

静态成员函数、友元函数:不属于某个对象
内联函数:不是动态的,是编译时确定的
构造函数:初始化数据成员的,是确定的,不是动态确定的

虚函数不能是:静态成员函数、友元函数、内联函数、构造函数
虚函数可在类中声明、定义,在继承的子类中可以重定义(也可以不重定义)
虚函数可以是析构函数
虚函数父类有多次继承的子类,子类用该函数时,用的是这个父类的该函数!
虚函数不能被重载覆盖,子类对象引用子类虚函数会出现错误!

虚函数使用规则:
类型兼容
子类可以重定义
如何被访问:成员函数、指针、引用

虚析构函数

virtual ~类名();

父类的析构函数是虚函数,其下面的子类都是虚析构函数

好处:
父类类型指针可以的调用恰当的析构函数 完成不同类型对象的清理

使用情景:
父类类型指针,子类的对象清理

抽象类

抽象类:含有纯虚函数的类

纯虚函数:
virtual 函数类型 函数名(形参表)=0

空虚函数
virtual 函数类型 函数名(形参表){ 空的!}

1 抽象类不能实例化(不能有自己的对象),只能被其他类继承
2 子类继承抽象类,若不给出纯虚函数的定义,则自己也是抽象类
3 抽象类不能用作 参数类型、函数返回值、强制类型转换


函数模板:

调用:显式调用、隐式调用

显式调用:
函数名<数据类型表>(实参表);
max<double>(40, 68)

隐式调用:函数调用式 max(10,45)

max(10,45) 对应 int max(int, int)
max(10,45.0) 对应 int max(int, double)
max(10.0 , 45) 对应 double max(double,int)

系统函数:

复制的两个函数:

memcpy(目标地址,源地址,字节数n)
1、strcpy只能复制字符串,memcpy可复制任意内容,例字符数组、整型、结构体、类
2、复制的方法不同。
strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度

sizeof(数组名)
=sizeof(n*a[0])=sizeof(n*a[1])
=整个数组的字节数

sizeof(指针p)=4(32bit)8(64bit)
而不是p指向的数据的字节数

类模板

template<模板参数表>
class 类名
{
。。。
};


类模板的成员函数在类外定义形式:

template<模板参数表>
类型 类名<模板参数表>::函数名(参数表)
{函数体}

类模板实例化形式:
模板名<模板参数表> 对象名1,对象名2,。。。
具体:

class String {
public:
	char Str[20];
}

main()
{
	Student<String,float,100> S1;
	。。。
}

默认模板参数:

Student<char*> S1;
栈类模板
链表模板

STL:
standard template library 标准模板库
不让程序员重复发明轮子

STL编程:
逻辑上,泛型化程序设计
代码重用:现有模板程序代码开发程序
实现上,类型参数化,基于模板的标准库类,容器类

STL:
容器 container
迭代器 iterator
适配器 adaptor
算法 algorithm
函数对象 function object

容器(均是类模板):
顺序容器
关联容器

容器(均是类模板):
vector 向量
list 列表
deque 队列
set/multiset 集合
map/multimap 映射

顺序容器:
vector 向量,动态数组,查快 插删慢
list 双向链表,查慢 插删快
deque 双端队列,包含vector、list两者的优点特性,可看做两者的融合

关联容器:
set/multiset 集合
map/multimap 映射

顺序容器:
vector 有成员方法
list 无成语方法
deque 有成员方法

异常:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_1403034144

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值