C++多态性及虚函数

C++多态性:虚函数的调用原理 C++多态性:虚函数的调用原理多态性给我们带来了好处:多态使得我们可以通过基类的引用或指针来指明一个对象(包含其派生类的对象),当调用函数时可以自动判断调用的是哪个对象的函数。一个函数说明为虚函数,表明在继承的类中重载这个函数时,当调用这个函数时应当查看以确定调用哪个对象的这个函数。普通函数的处理:一个特定的函数都会映射到特定的代码,无论时编译阶段还是连接阶段,编译器都能计算出这个函数 阅读详情

多态性

多态性是面向对象程序设计的重要特性

一种接口,多种方法

在C++程序设计中,多态性是指具有不同功能的函数可以使用同一个函数名。

在面向对象方法中多态性一般表述为:向不同的对象发送同一个消息,不同的对象在接收时会产生不同行为。

多态性可分为:静态多态性和动态多态性

静态多态性(编译多态性):在程序编译时系统就能决定调用哪个函数,通过重载实现(包括函数的重载、运算符的重载)。

动态多态性(运行多态性):在程序运行的时候才动态的确定操作所针对的对象,通过虚函数实现。


虚函数

在同一个类中不能定义两个名字相同、参数类型及个数都相同的函数,否则就是“重复定义”(多重继承下来两个完全相同的不算重复定义)。而在继承层次结构中,不同层次中可以出现名字、参数类型、参数个数都相同的函数,因为在不同层次中编译系统会按照同名屏蔽的原则调用派生类的函数。

特别说明:析构函数也可以为虚,实现原理相同(虚函数表实现),但构造函数不能为虚,因为指向vtable的指针其实是存储在对象的内存空间的。问题出来了,如果构造函数是虚的,就需要通过 vtable来调用,可是对象还没有实例化,也就是内存空间还没有,怎么找vtable呢。

谭浩强版本中:虚函数的作用是允许在派生类中重新定义与基类同名的函数,并通过基类指针或引用来访问基类和派生类中的同名函数。

个人觉得前半句不妥,即无虚函数仍可以在派生类中重新定义与基类同名的函数,举例说明:

class A
{
	public:
	void ss()
	{cout<<"hello"<<endl;}
};
class B:public A
{
	public:
	void ss()
	{cout<<"world"<<endl;}	
};
int main()
{
	B b1;
	b1.ss();	//调用的是类B中新增的ss()函数 
	b1.A::ss(); //调用的是类A中的ss()函数
}

虚函数真正作用:突破了无法通过基类指针或引用去调用派生类对象中的成员函数的限制,从而实现了动态多态性。

举例分析:

class A
{
	public:
	virtual void ss()
	{cout<<"hello"<<endl;}
};
class B:public A
{
	public:
	void ss()
	{cout<<"world"<<endl;}	
};
class C:public B
{
	public:
	void ss()
	{cout<<"!!"<<endl;}	
};
void show(A *p)
{
	p->ss();
}
int main()
{
	A a1;
	B b1;
	C c1; 
	show(&a1);
	show(&b1);	
	show(&c1);
}

代码中将类A中的ss()函数定义成虚函数,通过采用虚函数的方式,你不用管传入show函数的实参哪个派生类的指针,都可以通过基类形参指针,调用对应派生类的ss()函数从而产生不同的效果,即为多态的体现。如果不采用虚函数的方式的话,你得给各个派生类分别写一个函数,这大大增加了代码的复杂度。

通过基类引用的方法实现,只需稍作修改:

void show(A &p)
{
	p.ss();
}
int main()
{
	A a1;
	B b1;
	C c1; 
	show(a1);
	show(b1);	
	show(c1);
}
对于引用的方法适用于作为形参,若作为实参将不能使用引用的方法

class A
{
	public:
	virtual void pp()
	{
		cout<<"hello"<<endl;
	}
};
class B:public A
{
	public:
	void pp()
	{
		cout<<"world"<<endl;
	}	
};
int main()
{
	A a1;
	B b1;
	A &p=a1;
	p.pp();
	p=b1;	//引用变量是无法重新绑定,这里只是b1赋值给a1 
	p.pp();
}
引用变量是无法重新绑定,所以p=b1只是b1赋值给a1,而赋值只是数据成员的传递,成员函数无法传递,于是只是执行了b1中对应基类A的数据成员传递给了基类A的对象a1, 因为b1继承a1所以b1中对应基类A的数据成员即为a1中的数据成员。

虚函数的使用方式:

(1)在基类用关键字virtual声明成员函数为虚函数,若在类外定义虚函数则,可不用加virtual。(这里说的基类并非一定要最原始的类,而是任何一个类都可作为基类,继承它的类自然成了派生类)

(2)在派生类中重新定义此函数,要求函数名、函数类型、函数参数个数及类型全部与基类虚函数相同。

特别注意:当一个成员函数被声明为虚函数后,其派生类中的同名函数自动成为虚函数,可以不加virtual,但为了代码更清晰,一般都会加上virtual。

(3)定义一个指向基类对象的指针或引用变量,利用指针或引用调用同一类族中某一对象的虚函数。

注意:不能定义了派生类对象指针或引用,然后想指向或引用基类对象。


虚函数的实现原理:

<参考>http://blog.youkuaiyun.com/haoel/article/details/1948051


采用了虚函数表实现虚函数

虚函数表:它是一个指针数组,存放每个虚函数的入口地址,虚函数的实现即通过了虚函数表(Virtual Table)。

注意的是,编译器会为每个有虚函数的类创建一个虚函数表,该虚函数表将被该类的所有对象共享,这个指针数组并非存于某个对象中而是进行单独存储,但各个对象实例都有指向虚函数表的指针,并存于对象中。

这张表解决了继承、覆盖的问题,保证其真实反应实际的函数。这样,在有虚函数的类的实例中这个表被分配在了这个实例的内存中,所以,当我们用父类的指针来操作一个派生类的时候,这张虚函数表就显得由为重要了,它就像一个地图一样,指明了实际所应该调用的函数。

C++的编译器应该是保证指向虚函数表的指针存在于对象实例中最前面的位置(这是为了保证取到虚函数表的有最高的性能——如果有多层继承或是多重继承的情况下)。 这意味着我们通过对象实例的地址得到这张虚函数表,然后就可以遍历其中函数指针,并调用相应的函数。

假设我们有这样的一个类:

class Base 
{ 
public:
	virtual void f() { cout << "Base::f" << endl; }
	virtual void g() { cout << "Base::g" << endl; }
	virtual void h() { cout << "Base::h" << endl; }
};
按照上面的说法,我们可以通过Base的实例来得到虚函数表。 下面是实际例程:
typedef void(*Fun)(void);
 
	Base b;
 
	Fun pFun = NULL;
	
	cout << "虚函数表地址:" << (int*)(&b) << endl;
	cout << "虚函数表 - 第一个函数地址:" << (int*)*(int*)(&b) << endl;
 
	// Invoke the first virtual function 
	pFun = (Fun)*((int*)*(int*)(&b));
	pFun();
实际运行结果如下:

虚函数表地址:0012FED4

虚函数表 — 第一个函数地址:0044F148

Base::f

通过这个示例,我们可以看到,我们可以通过强行把&b转成int *,取得虚函数表的地址,然后,再次取址就可以得到第一个虚函数的地址了,也就是Base::f(),这在上面的程序中得到了验证(把int*强制转成了函数指针)。通过这个示例,我们就可以知道如果要调用Base::g()和Base::h(),其代码如下:

(Fun)*((int*)*(int*)(&b)+0);  // Base::f()
(Fun)*((int*)*(int*)(&b)+1);  // Base::g()
(Fun)*((int*)*(int*)(&b)+2);  // Base::h()
画个图解释一下。如下所示:

注意:在上面这个图中,我在虚函数表的最后多加了一个结点,表示虚函数表的结束结点。

下面,我将分别说明“无覆盖”和“有覆盖”时的虚函数表的样子。没有覆盖父类的虚函数是毫无意义的。我之所以要讲述没有覆盖的情况,主要目的是为了给一个对比。在比较之下,我们可以更加清楚地知道其内部的具体实现。


一般继承(无虚函数覆盖)
下面,再让我们来看看继承时的虚函数表是什么样的。假设有如下所示的一个继承关系:

请注意,在这个继承关系中,子类没有重载任何父类的函数。那么,在派生类的实例中,其虚函数表如下所示:
 
对于实例:Derive d; 的虚函数表如下:

我们可以看到下面几点:
1)虚函数按照其声明顺序放于表中。
2)父类的虚函数在子类的虚函数前面。


一般继承(有虚函数覆盖)
 覆盖父类的虚函数是很显然的事情,不然,虚函数就变得毫无意义。下面,我们来看一下,如果子类中有虚函数重载了父类的虚函数,会是一个什么样子?假设,我们有下面这样的一个继承关系。

为了让大家看到被继承过后的效果,在这个类的设计中,我只覆盖了父类的一个函数:f()。那么,对于派生类的实例,其虚函数表会是下面的一个样子:

我们从表中可以看到下面几点,
1)覆盖的f()函数被放到了虚表中原来父类虚函数的位置,派生类处就不会再有。
2)没有被覆盖的函数依旧。

 
这样,我们就可以看到对于下面这样的程序,

Base *b = new Derive();

b->f();

由b所指的内存中的虚函数表的f()的位置已经被Derive::f()函数地址所取代,于是在实际调用发生时,是Derive::f()被调用了。这就实现了多态。


多重继承(无虚函数覆盖)
 下面,再让我们来看看多重继承中的情况,假设有下面这样一个类的继承关系。注意:子类并没有覆盖父类的函数。

对于子类实例中的虚函数表,是下面这个样子:

我们可以看到:
1)  每个父类都有自己的虚表。
2)  子类的成员函数被放到了第一个父类的表中。(所谓的第一个父类是按照声明顺序来判断的)

 这样做就是为了解决不同的父类类型的指针指向同一个派生类实例,而能够调用到实际的函数。

 
 
多重继承(有虚函数覆盖)
下面我们再来看看,如果发生虚函数覆盖的情况。
下图中,我们在子类中覆盖了父类的f()函数。

下面是对于子类实例中的虚函数表的图:

我们可以看见,三个父类虚函数表中的f()的位置被替换成了子类的函数指针。这样,我们就可以任一静态类型的父类来指向子类,并调用子类的f()了。如:

Derive d;
Base1 *b1 = &d;
Base2 *b2 = &d;
Base3 *b3 = &d;
b1->f(); //Derive::f()
b2->f(); //Derive::f()
b3->f(); //Derive::f()
 
b1->g(); //Base1::g()
b2->g(); //Base2::g()
b3->g(); //Base3::g()

C++ 虚函数和多态性 虚函数和多态性 多态性的概念 实现多态性的基石——虚函数 虚函数的概念和特性 3. 虚特性的继承 虚特性是可以被继承的。在继承树上,一旦基类中的某个函数被声明成是虚的,那么其所有后代中原型相同的函数都将是虚的。 如果派生类中重载了一个原型不同的函数,那么这个函数将会怎样来影响虚特性的遗传呢? 可以看到,tiger类中的what(int)由于与基类中的同名函数原型不同,因此失去了虚特性,而且我们不能... 阅读详情

相关推荐

C++实验:多态性与虚函数

C++实验:多态性与虚函数 1. 实验目的 (1) 了解多态性的概念。 (2) 了解虚函数的作用及使用方法。 (3) 了解静态关联和动态关联的概念和用法。 (4) 了解纯虚函数和抽象类的概念和用法。 2.实验内容 事先编写好程序,上机调试和运行程序,分析结果。 (1)声明Point (点)类,由Point类派生出Circle (圆)类,再由Circle类派生出Cylinder (圆柱体)类。将类的定义部分分别作为3个头文件,对它们的成员函数的声明部分分别作为3个源文件( .cpp文件),在主函数中

阡陌笙的博客 2670

虚函数的一些使用

1、虚函数的使用 首先插入一段代码 #include <iostream> #include <string> using namespace std; //声明基类Student class Student { public: Student(int, string,float); //声明构造函数 void display( );//声明输出函数 protected: //受保护成员,派生类可以访问 int num; string name;

shyboyandgirl的博客 1578

PCB设计必看:铜皮厚度与载流量的黄金比例(附实用对照表)

本文深入探讨了PCB设计中铜皮厚度与载流量的关键关系,提供了实用的对照表和设计技巧。通过分析基础原理、标准选择策略及常见误区,帮助工程师优化PCB设计,确保电路板的可靠性和安全性。特别适用于需要处理大电流或高频应用的电子设计场景。

milk8的博客 512

虚函数的使用方法

( 1 )在基类用 virtual 关键字声明成员函数为虚函数。 这样就可以在派生类中重新定义此函数,为它赋予新的功能,并能方便地被调用 。 在类 外定义虚函数时,不必再加 virtual 关键字。( 2 )在派生类中重新定义此函数,要求函数名 、 函数类型 、 函数参数个数和类型全部与 基类的虚函数相同,并根据派生类的需要重新定义函数体。 C++规定,当一个成员函数被声 明为虚函数后,其派生类中...

sinat_19868271的博客 5616

NVIDIA DGX Spark实战:如何在桌面上轻松运行200B参数大模型?

本文详细介绍了如何利用NVIDIA DGX Spark在桌面端轻松运行200B参数大模型。通过实战演示,从系统初始化、模型获取部署到内存管理与性能调优,重点解析了其统一内存架构如何解决本地推理的显存瓶颈,并探讨了进行轻量化微调(如LoRA)的可能性,为AI开发者和研究团队提供了高效的本地化大模型操作方案。

weixin_29054195的博客 886

Moveit Servo学习

MoveIt Servo功能与配置指南 摘要:本文介绍了MoveIt Servo的功能特性,包括支持关节速度、末端执行器速度和位置控制,以及安全功能如奇点检查、碰撞检测等。通过示例展示了如何运行伺服控制demo,详细解析了关键节点和话题。最后以睿尔曼rml_63机器人为例,讲解了如何自定义伺服配置文件,包括环境设置、输入输出参数配置、平滑滤波器和规划场景监控等关键配置项。文章提供了从基础使用到自定义机器人配置的完整指导,帮助开发者实现高效的实时运动控制。

Fisher的博客 1176

虚函数详解及应用场景

虚函数详解及应用场景

qq_46017342的博客 3676

高通ISP模块全解析:从Raw到JPEG的18个关键处理步骤(附避坑指南)

本文全面解析高通ISP模块从Raw到JPEG的18个关键处理步骤,涵盖原始数据预处理、色彩科学处理链、画质增强与降噪等核心环节。通过实战调优经验,揭示ISP架构中的技术原理与工程实践要点,帮助开发者避免常见问题,提升移动影像处理质量。

weixin_30399155的博客 360

C++虚函数操作指南

虚函数是基类中声明的成员函数,且使用者期望在派生类中将其重新定义。那么,在 C++ 中,什么是虚函数呢?在 C++ 中,通常将虚函数用于实现运行时多态,该特性由 C++ 提供,适用于面向对象编程。我们将在下文更为详细地讨论运行时多态。不论函数调用所使用的指针或引用类型如何,虚函数最为重要的工作是确保函数调用正确。虚拟函数是基类中声明的成员函数,将在派生类中重新定义。在 C++ 中,使用虚函数来实现运行时多态。

高空的博客 2543

从零到一:Silvaco中跨导曲线的自动化脚本实现

本文详细介绍了如何使用Python脚本在Silvaco中实现跨导曲线(gm曲线)的自动化分析,包括数据加载、跨导计算和结果可视化。通过自动化处理Id-Vg曲线,显著提升半导体器件工程师的工作效率,特别适用于工艺优化和DOE分析。文章还提供了批量处理和关键参数提取的高级技巧,帮助工程师快速掌握Silvaco脚本开发。

nn3456的博客 568

【unity小技巧】常用的方法属性和技巧汇总(长期更新,2025/07/02更新)

Unity开发技巧摘要 本文汇总了Unity开发中的实用技巧,包括移动控制、力应用、物体翻转、单例模式实现等。移动方面介绍了MoveTowards、MovePosition、Translate等方法的区别与应用场景;力应用部分详解了AddForce系列方法的参数和使用方式;物体翻转对比了三种实现方案;单例模式提供了标准实现和泛型优化版本;还收录了绝对值计算、鼠标检测、旋转控制、数值取整等实用代码片段。这些经过验证的技巧能有效提升开发效率,文章将持续更新补充新的实用内容。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 3350

虚函数的使用

1.虚函数的注意点 1)重写,重写是针对与虚函数的,即子类的同名函数重写父类的同名虚函数;而覆盖是针对于一般函数的 2)虚,只针对于函数成员而不能使用于数据成员 3)子类重写的函数,即跟父类虚函数同名的函数,默认是虚函数,可以显式的加上virtual,也可以不加 4)重写要求较高,要求两个函数的输入参数得相同,同时在大部分情况下,也要求返回值的类型相同,除非协变,返回值是当前的类、类指针或...

renwu 2902

大模型LoRA微调调参的实战技巧(持续更新)

本文主要介绍了大模型LoRA微调调参的实战技巧,希望对学习大语言模型的同学们有所帮助。 文章目录 1. 前言 2. 实战技巧

herosunly的博客 20万+

C++ 虚函数与多态性

多态性 面向对象程序设计中的多态性是指向不同的对象发送同一个消息,不同对象对应同一消息产生不同行为。在程序中消息就是调用函数,不同的行为就是指不同的实现方法,即执行不同的函数体,也可以这样说就是实现了“一个接口,多种方法” ...

Chroniccandy的博客 2512

嵌入式模拟电路面试题大全及参考答案(持续更新)

高输入阻抗:由于晶体管的基极-发射极(BJT)或栅极-源极(MOSFET)电压很低,跨导放大器具有很高的输入阻抗。低输出阻抗:晶体管的集电极-发射极或漏极-源极电阻较低,提供较低的输出阻抗。电压控制:输入信号控制晶体管的跨导,从而控制输出电流。晶体管:作为放大器的核心,可以是BJT或MOSFET。偏置电路:为晶体管提供稳定的工作点,确保其在放大区域内工作。负载电阻:与晶体管的集电极或漏极连接,将电流转换为电压。晶体管的选择:根据所需的增益、速度和功率消耗选择合适的晶体管。偏置稳定性。

大模型大数据攻城狮的专栏 989

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

CPP多态性与虚函数

文章目录多态性与虚函数面向对象程序设计中的多态性派生类与基类对象之间的赋值虚函数虚析构函数纯虚函数(抽象类)虚函数与虚基类派生类中重定义基类中的重载函数虚函数动态绑定的实现原理 多态性与虚函数 面向对象程序设计中的多态性 多态性(polymorphism) 调用同一个函数名,根据需要实现不同的功能。 编译时的多态性:静态多态(函数重载、运算符重载) 运行时的多态性:动态多态(虚函数) 函数重载和运算符重载实现的多态性属于静态多态性,在程序编译时就能决定调用的是哪个函数。静态多态性又称编译时的多态性。静态

SongyangJi 1589

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

【Journey to the Cpp】Series之多态性与虚函数

关卡三:多态性与虚函数

m0_46308522的博客 754

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

C++【05】多态性与虚函数

一、多态性的概念 多态性(polymorphism)是面向对象程序设计的一个重要特征。如果一种语言只支持类而不支持多态,是不能被称为面向对象语言的,只能说是基于对象的,如Ada、VB。C++支持多态性,利用多态性可以设计和实现一个易于扩展的系统。 在C++程序设计中,多态性是指具有不同功能的函数可以用同一个函数名,这样就可以用一个函数名调用不同内容的函数。在面向对象方法中一般是这样表述多态性的: 向不同的对象发送同一个消息,不同的对象在接收时会产生不同的行为(即方法)。也就是说,每个对象可以用自己的方式去响

The_Handsome_Sir的博客 1416

C++重载 虚函数 纯虚函数 多态性

C++编程语言是一款应用广泛,支持多种程序设计的计算机编程语言。我们今天就会为大家详细介绍其中C++多态性的一些基本知识,以方便大家在学习过程中对此能够有一个充分的掌握。   多态性可以简单地概括为“一个接口,多种方法”,程序在运行时才决定调用的函数,它是面向对象编程领域的核心概念。多态(polymorphisn),字面意思多种形状。   C++多态性是通过虚函数来实现的,虚函数允许子类重新定

犀利虫的专栏 3204

C++的多态性和虚函数

1.作为新手学习C++的多态性,首先应该了解C++的多态性有何现实意义? 多态性的现实意义在于可以用相同的函数名来标识这些函数,达到用同样的接口访问不同功能的函数,从而实现“一个接口,多种方法”。通俗点说就是可以不用像C语言中为了求多种图形的面积而针对不同的图形各设计了一个名字独立的函数,在C++中只要设计一个专门用于求面积的函数名字即可,这个专门用于求面积的函数名字可以作为求各种图形面积...

jacket_的博客 795

C++多态性与虚函数

C++多态性与虚函数 本讲基本要求     * 掌握:多态性的概念;虚函数的定义及应用。     * 理解:对象与类函数的静态关联与动态关联。     重点、难点: :多态性的概念;虚函数的定义及应用。 一、多态性的概念 定义:    多态性(polymorphism)是面向对象程序设计的一个重要特征。利用多态性可以设计和实现一个易于扩展的系统。多态性是指具有不同功能的函数

蜗牛之旅 1362

C++虚函数与多态性

C++虚函数与多态性 开发工具与关键技术:C++、VisualStudio 作者:何任贤 撰写时间:2019年06月01日 多态性(Polymorphism)是指一个名字,多种语义;或界面相同,多种实现,而重载函数是多态性的一种简单形式。 虚函数允许函数调用与函数体的联系在运行时才进行,称为动态联编,而联编是指一个程序模块、代码之间互相关联的过程,而静态联编,是程序的匹配、连接在编译阶段实现,也...

qq_41973378的博客 260

C++之多态性与虚函数

面向对象程序设计中的多态性是指向不同的对象发送同一个消息,不同对象对应同一消息产生不同行为。在程序中消息就是调用函数,不同的行为就是指不同的实现方法,即执行不同的函数体。也可以这样说就是实现了“一个接口,多种方法”。  从实现的角度来讲,多态可以分为两类:编译时的多态性和运行时的多态性。前者是通过静态联编来实现的,比如C++中通过函数的重载和运算符的重载。后者则是通过动态联编来实现的,在C++中运

张勤一 1606

C++ 多态性与虚函数

四 多态性与虚函数 1.多态性 多态性:对同一的消息,不同对象有不同的响应方式。 多态性分两种:静态多态性 和 动态多态性。 静态多态性 是通过函数的重载实现的,在程序编译时系统就能决定要调用的是哪个函数,也称编译时的多态性。 动态多态性 是通过虚函数实现的,在程序运行过程中才动态地确定操作所针对的对象。 坐公交车前确定了路线就好比静态多态性,而临时决定路线就好比动态多态性。 2.虚函数 在类...

PFzcnds8310__的博客 595

C++:多态性与虚函数

文章目录多态性在生活中的体现多态性在C++中的体现编译时的多态性运行时的多态性虚函数纯虚函数抽象类 多态性在生活中的体现 煤气炉是炉子中的一种 微波炉也是炉子中的一种 煤球炉是炉子中的一种 他们都可以煮东西 微波炉可以煮鸡蛋 (1)打开微波炉的门 (2)放入鸡蛋 (3)设定时间 (4)设定微波强度 (5)关上门 (6)启动 煤气炉可以煮鸡蛋 (1)鸡蛋放到小锅里 (2)把小锅放到煤气炉上 (3)打开煤气罐阀门 (4)电子点火 (5)设定火力强度 (6)盖上锅盖 (7)等待鸡蛋熟 多态性在C++中的体现

MOOG007的博客 226
上一篇: 作用域及域作用符
下一篇: 什么是操作系统
etherlai
博客等级 码龄16年 21粉丝 21原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值