C++基础运算符重载和继承

目录

学习内容:

1.运算符重载

1.1 运算符种类

1.2 运算符重载函数

1.3 调用原则和调用机制

1.4 运算符重载函数的格式

1.5 算术运算符

1.6 赋值类运算符重载

1.7 关系运算符重载函数

1.8 单目运算符

1.9 自增自减运算

1.10 插入和提取运算符重载

1.11 类型转换运算符

1.12 函数对象(仿函数)

1.13 运算符重载的限制

2. 静态成员 

2.1 静态成员变量

2.2 静态成员函数 

2.3 C/C++中static的总结(面试题) 

 3. 继承

3.1 继承的作用

3.2 继承的格式

3.3 继承方式 

3.4 继承过程中的成员


学习内容:

1.运算符重载

1.1 运算符种类

        单、算、移、关、逻辑、条件表达式、赋值、逗号

1.2 运算符重载函数

        1> 函数名:统一为 operator# //这里的#表示要被重载的运算符

        2> 参数:根据运算符的功能和位置而定,全局函数版双目运算符参数有两个,成员函数版双目运算符参数一个

                全局函数版,单目运算符参数有一个,成员函数版单目运算符参数无

        3> 返回值:根据运算符的特征而定

1.3 调用原则和调用机制

        调用时机:当对象使用该运算符时,系统自动调用运算符重载函数

        调用机制:左调右参原则,运算符左侧是函数的调用者,运算符右侧是函数的参数

                例如:a = b; //a.operator=(b);

                                s1 + s2; //s1.operator+(s2);

1.4 运算符重载函数的格式

        1> 任意一个运算符重载都有两个版本:成员函数版和全局函数版

        2> 实际使用过程中,只实现一种重载的情况,常用成员函数版

1.5 算术运算符

        1> 种类:+、-、*、/、%

        2> 算术运算符属于双目运算符,格式:L # R; L表示左操作数,#表示运算符号,R表示右操作数

        3> 左操作(L):既可以是左值也可以是右值

             右操作数(R):既可以是左值也可以是右值

              运算结果:只能是右值

        4> 格式:

                成员函数版:const 类名 operator#(const 类名 &R) const

                解析:第一个const保护运算结果不被修改

                            第二个const保护右操作数在运算过程中不被修改

                            第三个const保护左操作数自身在运算过程中不被修改

                全局函数版:const 类名 operator#(const 类名 &L,const 类名 &R)

1.6 赋值类运算符重载

        1> 种类:=、+=、-=、*=、/=、%=

        2> 赋值运算符属于双目运算符,格式:L # R; L表示左操作数,#表示运算符号,R表示右操作数

        3>    左操作(L):只能是左值

                右操作数(R):既可以是左值也可以是右值

                运算结果:左操作数自身的引用

        4> 格式:

                成员函数版:类名 & operator#(const 类名 &R)

                全局函数版:类名 & operator#( 类名 &L,const 类名 &R)

1.7 关系运算符重载函数

        1> 种类:>、=、

        2> 关系运算符属于双目运算符,格式:L # R; L表示左操作数,#表示运算符号,R表示右操作数

        3>    左操作(L):既可以是左值也可以是右值

                右操作数(R):既可以是左值也可以是右值

                运算结果:bool类型的右值

        4> 格式:

                成员函数版:const bool operator#(const 类名 &R) const

                全局函数版:const bool operator#(const 类名 &L,const 类名 &R)

1.8 单目运算符

        1> 种类:-(负号) 、!

        2> 格式:# R; #表示运算符号,R表示右操作数

        3> 操作数(R):既可以是左值也可以是右值

                运算结果:同类的一个右值

        4> 格式:

                成员函数版:const 类名 operator#() const

                全局函数版:const bool operator#(const 类名 &R)

1.9 自增自减运算

        1> 种类:++ 、 --

        2> 格式:# R; #表示运算符号,R表示右操作数

        3> 操作数(R):只能是左值

                运算结果:

        前置:是自身的引用

        成员格式:类名 &operator#()

        全局格式:类名 &operator#(类名 &R)

        后置:临时值

        成员格式:类名 operator#(int)

        全局格式:类名 operator#(类名 &R, int)

1.10 插入和提取运算符重载

        1> 插入和提取运算符的来源        

namespace std {

        ostream cout;

        istream cin;

}

        2> 由于运算符重载函数的调用遵循左调有参原则,所以,自定义类的重载函数,需要流对象和自定义类的对象

        例如:cout<<c  //cout.operator<<(c);

        3> 此时,原则上来说,需要在流所在的类对象中,写成员函数,难度较大,所以,对于该类的重载函数,我们只能实现全局函数版,将该函数作为类的友元函数   

        4> 格式:

                ostream& operator

                istream& operator>>(istream &L, 类名 &R)

1.11 类型转换运算符

        1> 有时,需要将类对象进行强制类型转换为其他数据类型,此时就需要在类体内提供类型转换运算符重载函数

        2> 定义格式: operator 要转换的类型() { 返回对应类型的数据 }

1.12 函数对象(仿函数)

        1> 本质上就是重载 () 运算符,由于调用时,跟函数调用一样,所以称为仿函数

        2> 定义格式: operator() (参数列表) {函数体内容}

        3> 调用格式:对象名(实参名); //对象 . operator() (实参名)

1.13 运算符重载的限制

1> 运算符重载只能在已有的运算符基础上进行重载,不能凭空捏造一个运算符

2> 运算符重载不能更改运算符的本质:如不能在加法运算符重载中实现减法

3> 运算符重载不能改变运算符的优先级

4> 运算符重载不能改变运算符的结合律

5> 运算符重载函数不能设置默认参数

6> 成员函数版的参数要比全局函数版的参数少一个,原因是对象本身就是一个参数

#include <iostream>


using namespace std;


//定义一个复数类: 由实部和虚部组成的一个数据  a + bi
class Complax
{
private:
    int real;            //实部
    int vir;             //虚部


public:
    Complax() {cout<<"无参构造"<<endl;}            //无参构造
    Complax(int r, int v):real(r),vir(v) {cout<<"有参构造"<<endl;}   //有参构造
    ~Complax() {cout<<"析构函数"<<endl;}           //析构函数
    //定义输出函数
    void show()
    {
        if(vir > 0)
        {
            cout<<real << "+"<<vir<<"i"<<endl;
        }else
        {
            cout<<real << vir<<"i"<<endl;
        }
    }


    //定义成员函数版完成两个复数相加:实部+实部   虚部+虚部
    const Complax operator+(const Complax &R)const
    {
        Complax temp;       //无参构造
        temp.real = this->real + R.real;
        temp.vir = this->vir + R.vir;


        return temp;
    }


    //实现全局函数版,需要将全局函数版设置成友元函数
    friend const Complax operator-(const Complax &L, const Complax &R);


    //成员函数版完成加等于运算符重载: 实部 += 实部   虚部+=虚部
    Complax &operator+=(const Complax &R)
    {
        this->real += R.real;
        this->vir += R.vir;


        return *this;
    }


    //定义成员函数版完成关系运算符重载: 实部>实部   && 虚部>虚部
     bool operator>(const Complax &R)const
    {
        return this->real>R.real && this->vir>R.vir;
    }


     //定义成员函数版完成负号运算符重载:   实部 = -实部    虚部=-虚部
     const Complax operator-()const
     {
         Complax temp;
         temp.real = -this->real;
         temp.vir = -this->vir;


         return temp;
     }


     //定义成员函数版完成++前置运算: 实部 +=1   虚部+=1
     Complax &operator++()
     {
         this->real++;
         this->vir++;


         return *this;
     }


     //定义成员函数版完成++后置运算: 实部 +=1   虚部+=1
     Complax operator++(int)        //这里括号中的int仅仅起到占位作用,使用的是哑元
     {
         Complax temp;
         temp.real = this->real++;
         temp.vir = this->vir++;


         return temp;
     }


     //将插入运算符重载函数,设置成友元函数
     friend ostream & operator<<(ostream &L, const Complax &R);


     //定义类型转换运算符重载函数
     operator int()
     {
         return this->real + this->vir;
     }


     //重载小括号运算符,完成仿函数
     void operator()(string msg)
     {
         cout << msg<< endl;
     }




};


//定义全局函数版完成两个复数相减
const Complax operator-(const Complax &L, const Complax &R)
{
    Complax temp;       //无参构造
    temp.real = L.real - R.real;
    temp.vir = R.vir - R.vir;


    return temp;
}


//自定义插入运算符重载函数:只能实现全局函数版
ostream & operator<<(ostream &L, const Complax &R)
{
    //输出内容
    if(R.vir > 0)
    {
        L<<R.real << "+"<<R.vir<<"i"<<endl;
    }else
    {
        L<<R.real << R.vir<<"i"<<endl;
    }


    //返回左操作数自身
    return L;
}


int main()
{
    Complax c1(5,7);           //有参构造
    c1.show();                //5+7i
    Complax c2(3, -2);            //有参构造
    c2.show();                    //3-2i
    cout<<"**************************************"<<endl;


    Complax c3 = c1+c2;       //调用加号 运算符重载函数
    c3.show();                //8+5i
    cout<<"**************************************"<<endl;


    (c1+=c2) += c3;          //调用加等于运算符重载函数
    c1.show();            //16+10i
    c2.show();             //3-2i
    c3.show();              //8+5i
    cout<<"**************************************"<<endl;


    if(c1>c2)                      //调用关系运算符重载函数
    {
        cout<<"yes"<<endl;
    }else
    {
        cout<<"no"<<endl;
    }
    cout<<"**************************************"<<endl;


    Complax c4 = -c1;          //调用负号运算符重载
    c4.show();                  // -16 - 10i
    cout<<"**************************************"<<endl;


    /*
    int num = 5;
    num++++;          //后置自增后,返回结果是一个右值
    ++++num;          //前置自增后,返回的结果是一个左值
    */
    Complax c5 = ++++c1;            //前置自增,先加再用
    c5.show();         //18+12i
    c1.show();         //18+12i


    cout<<"**************************************"<<endl;


    Complax c6 = c1++;        //后置自增,先用再加
    c6.show();             //18+12i
    c1.show();             //19+13i
    cout<<"**************************************"<<endl;


    cout<<c1 <<c2;          //cout.operator<<(c1);
    cout<<"**************************************"<<endl;


    int num = (int)c1;         //调用强制类型转换函数
    cout<<"num = "<<num<<endl;      //32
    cout<<"**************************************"<<endl;


    //仿函数的调用
    c1("hello world");
    cout<<"**************************************"<<endl;




    return 0;
}

2. 静态成员 

        所谓静态成员,就是将类中的某个或某几个成员,依赖于类对象而独立存

        在程序编译阶段,就给静态成员分配空间,即使没有类对象,静态成员的空间依然已经分配

        相当于在类体内,定义一个生命周期比较常的数据

        静态成员分配,静态成员变量和静态成员函数

2.1 静态成员变量

        1> 定义格式:在定义成员变量时,在前面加关键字static,该成员变量就是静态成员变量

        2> 静态成员的权限一般为public,必须在全局处进行定义,类内只是声明,如果没有在全局处进行定义,那么默认为0

        3> 静态成员变量,不占用类对象的内存空间,在编译时系统就分配了内存空间

        4> 虽然静态成员不占用类对象的空间,但是,也可以通过类对象调用静态成员变量

        5> 静态成员变量的访问:有两种访问形式

                对象名.静态成员变量

                类名::静态成员变量

        6> 所有类对象,共享该静态成员变量,无论实例化多少个类对象,静态成员只有一份

        7> 静态成员变量,从功能上来说,可以理解成是一个全局变量,但是相比于全局变量而言,静态成员变量更加体现了类的封装性

#include <iostream>


using namespace std;


class Stu
{
private:
    int age;


public:
    static int flag;           //类内声明


public:
    Stu() {}
};


//类外定义静态成员变量
int Stu::flag = 520;




int main()
{
    cout<<sizeof(Stu)<<endl;         //4说明静态成员 变量不占用类对象的空间
    //通过类对象名直接访问静态成员变量,不用关心是否已经实例化对象了
    Stu::flag = 999;      //可读可写
    cout<<"Stu::flag = "<<Stu::flag<<"    &Stu::flag = "<<&Stu::flag<<endl;      //520


    //使用方法
    Stu s1;
    cout<<"s1.flag = "<<s1.flag<<"    &s1.flag = "<<&s1.flag<<endl;      //520


    Stu s2;
    s2.flag = 1314;     //可读可写
    //所有类的对象,共享静态成员变量,程序启动后,静态成员变量只有一份
    cout<<"s2.flag = "<<s2.flag<<"    &s2.flag = "<<&s2.flag<<endl;      //1314
    cout<<"s1.flag = "<<s1.flag<<"    &s1.flag = "<<&s1.flag<<endl;      //1314




    return 0;
}

2.2 静态成员函数 

        1> 定义格式:在定义成员函数前加关键字static,那么该函数就是静态成员函数

        2> 和静态成员变量一样,不依附于某个具体的类对象,属于整个类的

        3> 静态成员函数的调用方式也有两种:通过类对象调用,通过类名直接调用

        4> 静态成员函数中,只能使用静态成员变量,不能使用非静态成员变量

        5> 静态成员变量中没有this指针,但是,同名的静态成员函数与非静态成员函数不构成重载关系

#include <iostream>


using namespace std;


class Stu
{
private:
    int age = 18;


public:
    static int flag;           //类内声明


public:
    Stu() {}


    //非静态成员函数
    void show()
    {
        cout<<"age = "<<this->age<<"     falg = "<<this->flag<<endl;
    }


    //静态成员函数,与同名的非静态成员函数不构成重载关系
    static void show(int)
    {
        cout<<"     falg = "<<flag<<endl;          //静态成员函数中吗,只能使用静态成员变量
    }
};


//类外定义静态成员变量
int Stu::flag = 520;




int main()
{
    cout<<sizeof(Stu)<<endl;         //4说明静态成员 变量不占用类对象的空间、


    //没有实例化对象之前,也可以直接调用静态成员函数
    //Stu::show();        //非静态成员函数,不能直接调用,必须依赖于类对象而存在
    Stu::show(1);          //可以直接调用静态成员函数


    //通过类对象名直接访问静态成员变量,不用关心是否已经实例化对象了
    Stu::flag = 999;      //可读可写
    cout<<"Stu::flag = "<<Stu::flag<<"    &Stu::flag = "<<&Stu::flag<<endl;      //520


    //使用方法
    Stu s1;
    cout<<"s1.flag = "<<s1.flag<<"    &s1.flag = "<<&s1.flag<<endl;      //520


    Stu s2;
    s2.flag = 1314;     //可读可写
    //所有类的对象,共享静态成员变量,程序启动后,静态成员变量只有一份
    cout<<"s2.flag = "<<s2.flag<<"    &s2.flag = "<<&s2.flag<<endl;      //1314
    cout<<"s1.flag = "<<s1.flag<<"    &s1.flag = "<<&s1.flag<<endl;      //1314
    cout<<"**************************************************************"<<endl;
    s1.show();            //非静态成员函数
    s1.show(1);           //使用类对象调用静态成员函数


    return 0;
}

2.3 C/C++中static的总结(面试题) 

        1> 修饰函数的局部变量,表示将当前变量独立于整个函数而存在,其生命周期随着整个程序的编译而产生,整个程序结束而终止,即使函数没有被调用,静态成员变量的内存空间也已经存在了,即使函数以及运行结束,静态成员变量的生命周期也没有结束。一次初始化,后期调用函数时,都具有保值功能。

        2> 修饰类中成员变量,为静态成员变量,不依附于类对象而存在,编译时系统分配空间,需要在全局处进行定义。即使没有类对象,也可以通过类名直接使用,也可以通过类对象进行使用。多个对象,共享静态成员变量,即使类对象的空间全部都释放后,静态成员的空间也没有结束,而是随着整个程序的结束而结束。

        3> 修饰全局变量时,表示限制作用域为当前文件,只能在当前文件内使用该全局变量,其他文件不能使用,即使使用extern也不可以

        4> 修饰全局函数时,表示限制作用域为当前文件,只能在当前文件内使用该函数,其他文件中不可以使用,即使使用了联合编译

        5> 修饰类中的成员函数,表示静态成员函数,独立于类体而存在,也可以使用类对象进行调用。即使没有实例化对象,也可以类名调用,静态成员函数中,只能访问静态成员变量,不能访问非静态成员变量。没有this指针。

 3. 继承

        面向对象三大特征:封装、继承、多态

        继承:所谓继承,就是基于一个已有的类,来创建出一个新类的过程叫做继承。主要提高代码的复用性。

3.1 继承的作用

        1> 实现代码的复用性

        2> 继承是实现多态的重要基础,没有继承就没有多态

3.2 继承的格式

class 子类名 :继承方式  class 父类名1, class 父类2。。。
{
    子类扩展的成员;
};

3.3 继承方式 

        1> 继承方式一共有三种:public、protected、private

        2> 回顾访问权限

                public:能在类内、子类以及类外被访问

                protected:能在类内、子类中被访问,类外不允许访问

                private:只能在类内被访问,子类、类外不允许被访问

        3>继承方式时父类中的所有访问权限在子类中的表现形式

父类:            public|protected|private|不能访问        public|protected|private|不能访问        public|protected|private|不能访问
继承方式                    public                                    protected                                private
子类:            public|protected|不能访问|不能访问        protected|protected|不能访问|不能访问    private|private|不能访问|不能访问
1、继承方式其实就是子类继承父类中访问权限的最高权限
2、默认继承方式是私有继承,常用的继承方式是public

        4> 访问权限也可以省略不写,如果省略不写,则默认的继承方式为私有的(private)

        5> 常用的继承方式是:public

#include <iostream>


using namespace std;


//定义父类
class Person
{
public:
    string name = "张三";        //公共成员姓名
protected:
    int pwd = 666666;            //受保护成员 银行卡密码
private:
    int money = 888888;           //私有成员 私房钱


public:
    Person() {}
    Person(string n, int p, int m):name(n),pwd(p),money(m) {}
    ~Person() {}


    void show()
    {
        cout<<"name = "<<name<<endl;         //父类中的公共权限下的成员,父类中可以访问
        cout<<"pwd = "<<pwd<<endl;         //父类中的受保护权限下的成员,父类中可以访问
        cout<<"money = "<<money<<endl;         //父类中的私有权限下的成员,父类中可以访问
    }
};


//基于一个已有的父类,定义一个新类
class Stu : public Person        //公共继承
//class Stu : protected Person       //受保护继承
//class Stu :  Person       //私有继承
{
public:
    string sex = "男";         //性别
protected:
    int score = 99;          //受保护成员分数
private:
    int age = 18;            //私有成员 年龄


public:
    Stu() {}
    ~Stu() {}


    //定义show函数
    void show()
    {
        cout<<"name = "<<name<<endl;         //从父类中继承的的公共权限下的成员,子类中可以访问
        cout<<"pwd = "<<pwd<<endl;         //从父类中继承的受保护权限下的成员,子类中可以访问
        //cout<<"money = "<<money<<endl;         //从父类中继承的私有权限下的成员,子类中不可以访问
        cout<<"sex = "<<sex<<endl;            //子类中的公共权限下的成员,子类中可以访问
        cout<<"score = "<<score<<endl;            //子类中的受保护权限下的成员,子类中可以访问
        cout<<"age = "<<age<<endl;            //子类中的私有权限下的成员,子类中可以访问
    }




};








int main()
{
    cout << sizeof (Person) << endl;
    cout << sizeof (Stu) << endl;


    //使用子类实例化对象
    Stu s1;
    //s1.show();


    cout<<"name = "<<s1.name<<endl;           //继承的公共权限下的成员,子类中也是公共的,类外可以访问
    //cout<<"pwd = "<<s1.pwd<<endl;               //继承的受保护的权限下成员,子类中也是受保护的,类外无法访问
    //cout<<"money = "<<s1.money<<endl;          //继承的私有成员,子类中无法访问,类外也无法访问
    cout<<"sex = "<<s1.sex<<endl;               //子类中的公共权限下的成员类外可以访问
    //cout<<"score = "<<s1.score<<endl;            //子类受保护的成员,类外无法访问
    //cout<<"age = "<<s1.age<<endl;                 //子类的私有成员,类外无法访问


    return 0;
}

3.4 继承过程中的成员

        1> 子类会继承父类中的所有成员,包括私有成员,只不过不能子类中不能使用父类的私有成员。如果非要使用父类的私有成员,需要在父类中提供public或者protected类型的接口函数完成对私有成员的操作。

        2> 想要完成对 子类从父类中继承下来的成员的初始化工作,需要在子类的初始化列表中,显性调用父类的构造函数来完成。如果没有显性调用父类的有参构造,那么系统会自动调用父类的无参构造,来完成对继承下来的成员的初始化工作。

        在这个过程中,虽然调用的父类的构造函数,但是并没有实例化父类对象,最终对象的个数只有一个

        3> 类与类之间的关系模型

                1、继承关系:is a 模型,是特殊的包含关系(has a模型)

                2、包含关系:has a模型,在一个类中,有另一个类的成员子对象

                3、友元关系:use a模型,在一个类中,使用另一类中的内容

#include <iostream>


using namespace std;


//定义父类
class Person
{
public:
    string name = "张三";        //公共成员姓名
protected:
    int pwd = 666666;            //受保护成员 银行卡密码
private:
    int money = 888888;           //私有成员 私房钱


public:
    Person() {cout<<"Person::无参构造"<<endl;}
    Person(string n, int p, int m):name(n),pwd(p),money(m) {cout<<"Person::有参构造"<<endl;}
    ~Person() {cout<<"Person::析构函数"<<endl;}


    void show()
    {
        cout<<"name = "<<name<<endl;         //父类中的公共权限下的成员,父类中可以访问
        cout<<"pwd = "<<pwd<<endl;         //父类中的受保护权限下的成员,父类中可以访问
        cout<<"money = "<<money<<endl;         //父类中的私有权限下的成员,父类中可以访问
    }
};


//基于一个已有的父类,定义一个新类
class Stu : public Person        //公共继承
//class Stu : protected Person       //受保护继承
//class Stu :  Person       //私有继承
{
public:
    string sex = "男";         //性别
protected:
    int score = 99;          //受保护成员分数
private:
    int age = 18;            //私有成员 年龄


public:
    Stu() {cout<<"Stu::无参构造"<<endl;}
    Stu(string n, int p, int m,string s, int s1, int a):sex(s), score(s1), age(a) {cout<<"Stu::有参构造"<<endl;}
    ~Stu() {cout<<"Stu::析构函数"<<endl;}


    //定义show函数
    void show()
    {
        cout<<"name = "<<name<<endl;         //从父类中继承的的公共权限下的成员,子类中可以访问
        cout<<"pwd = "<<pwd<<endl;         //从父类中继承的受保护权限下的成员,子类中可以访问
        //cout<<"money = "<<money<<endl;         //从父类中继承的私有权限下的成员,子类中不可以访问
        cout<<"sex = "<<sex<<endl;            //子类中的公共权限下的成员,子类中可以访问
        cout<<"score = "<<score<<endl;            //子类中的受保护权限下的成员,子类中可以访问
        cout<<"age = "<<age<<endl;            //子类中的私有权限下的成员,子类中可以访问
    }




};








int main()
{
    cout << sizeof (Person) << endl;
    cout << sizeof (Stu) << endl;


    //使用子类实例化对象
    Stu s1("zhangpp", 111111, 100, "男", 99, 18);    //有参构造
    //s1.show();


    cout<<"name = "<<s1.name<<endl;           //继承的公共权限下的成员,子类中也是公共的,类外可以访问
    //cout<<"pwd = "<<s1.pwd<<endl;               //继承的受保护的权限下成员,子类中也是受保护的,类外无法访问
    //cout<<"money = "<<s1.money<<endl;          //继承的私有成员,子类中无法访问,类外也无法访问
    cout<<"sex = "<<s1.sex<<endl;               //子类中的公共权限下的成员类外可以访问
    //cout<<"score = "<<s1.score<<endl;            //子类受保护的成员,类外无法访问
    //cout<<"age = "<<s1.age<<endl;                 //子类的私有成员,类外无法访问


    cout<<"**********************************************"<<endl;
    Person p1;
    cout<<"&p1 = "<<&p1<<"     &p1.name = "<<&p1.name<<endl;
    cout<<"**********************************************"<<endl;


    cout<<"&s1 = "<<&s1<<"     &s1.name = "<<&s1.sex<<endl;
    cout<<"**********************************************"<<endl;






    return 0;
}

  • 27
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值