C++ RAII机制

全面理解-C++中的RAII机制 是一种核心编程范式,通过对象的生命周期管理资源(如内存、文件句柄、网络连接等),确保资源的。通过 RAII,开发者可以编写更安全、更简洁的代码,是 C++ 区别于其他语言的核心优势之一。:利用栈对象的确定性析构机制,无论代码执行路径如何(包括异常),资源都会被正确释放。:将资源的获取与对象的初始化绑定,释放与对象的析构绑定。:对象独占资源所有权,避免资源泄漏和悬空指针。:操作要么完全成功,要么回滚到操作前的状态。:消除手动管理资源的风险,提升代码健壮性。:确保程序状态一致(不泄漏资源)。 阅读详情

RAII(Resource Acquisition Is Initialization)是一种编程范式,核心思想是:资源的生命周期与对象绑定——对象创建时获取资源,对象销毁时自动释放资源。这种机制通过构造函数和析构函数的配对执行,确保资源管理的安全性和一致性。

RAII 的核心原则

  1. 资源获取即初始化:在对象的构造函数中获取资源(如内存、文件句柄、网络连接等)。
  2. 资源释放即析构:在对象的析构函数中释放资源,确保资源被正确回收。

典型应用场景

1. 智能指针(C++)

通过 RAII 管理动态分配的内存,避免内存泄漏。

#include <memory>

// std::unique_ptr 独占资源所有权
{
    std::unique_ptr<int> ptr = std::make_unique<int>(42);
    // ptr 离开作用域时自动释放内存
}  // 无需手动 delete

// std::shared_ptr 共享资源所有权(引用计数)
{
    std::shared_ptr<int> a = std::make_shared<int>(10);
    std::shared_ptr<int> b = a;  // 引用计数+1
}  // 当最后一个 shared_ptr 销毁时释放内存
2. 文件操作

封装文件句柄,确保文件自动关闭。

class FileHandler {
public:
    explicit FileHandler(const char* path) 
        : file(fopen(path, "r")) {
        if (!file) throw std::runtime_error("Failed to open file");
    }
    
    ~FileHandler() {
        if (file) fclose(file);  // 自动关闭文件
    }
    
    // 禁用拷贝构造和赋值,避免重复释放
    FileHandler(const FileHandler&) = delete;
    FileHandler& operator=(const FileHandler&) = delete;
    
private:
    FILE* file;
};

// 使用示例
{
    FileHandler file("data.txt");
    // 文件在作用域结束时自动关闭
}
3. 互斥锁管理

自动加锁和解锁,避免死锁。

#include <mutex>

std::mutex mtx;

void func() {
    std::lock_guard<std::mutex> lock(mtx);  // 构造时加锁
    // 临界区代码
}  // 析构时自动解锁

RAII 的优势

  1. 异常安全:即使发生异常,对象的析构函数仍会被调用,资源得以释放。

    void func() {
        std::unique_ptr<int[]> arr = std::make_unique<int[]>(1000);
        // 若中间抛出异常,arr 会自动释放内存
    }
    
  2. 代码简洁:无需手动编写 try-finally 或 delete 语句。

  3. 资源管理统一:将资源生命周期与对象绑定,降低遗忘释放资源的风险。

对比手动资源管理

场景手动管理RAII
内存分配int* p = new int; delete p;std::unique_ptr<int> p;
文件操作FILE* f = fopen(); fclose(f);FileHandler f("path");
锁操作mutex.lock(); mutex.unlock();std::lock_guard lock(mutex);

自定义 RAII 类的设计要点

  1. 明确资源边界:清晰定义资源的获取和释放方式。
  2. 禁用拷贝或实现移动语义:避免资源被多次释放(如 std::unique_ptr)。
  3. 异常安全:确保构造函数和析构函数不抛出异常(或正确处理异常)。

总结

RAII 是 C++ 等语言中管理资源的核心范式,通过对象生命周期自动控制资源,显著提高代码的安全性和可维护性。智能指针、标准库容器(如 std::vector)、锁管理类(如 std::lock_guard)都是 RAII 的典型应用。掌握 RAII 是编写健壮、高效代码的关键。

一文详解C++ 中RAII机制 在 C++ 中,RAII(Resource Acquisition Is Initialization,资源获取即初始化) 是一种核心的资源管理机制,其核心思想是将资源的生命周期与对象的生命周期绑定:通过对象的构造函数获取资源,通过对象的析构函数释放资源,利用 C++ 中对象自动销毁的特性(离开作用域时编译器自动调用析构函数),确保资源的正确释放,避免资源泄漏。 阅读详情

相关推荐

C++中的RAII机制?

什么是RAII? RAII是Resource Acquisition Is Initialization(wiki上面翻译成 “资源获取就是初始化”)的简称,是C++语言的一种管理资源、避免泄漏的惯用法。利用的就是C++构造的对象最终会被销毁的原则。RAII的做法是使用一个对象,在其构造时获取对应的资源,在对象生命期内控制对资源的访问,使之始终保持有效,最后在对象析构的时候,释放构造时获取的资源。 为什么要使用RAII? 上面说到RAII是用来管理资源、避免资源泄漏的方法。那么,用了这么久了,也写了这么多程

sixstar666的博客 1202

RAII机制介绍

RAII机制介绍 RAII全程为Resource Acquisition Is Initialization(资源获取即初始化),RAII是C++语法体系中的一种常用的合理管理资源避免出现内存泄漏的常用方法。以对象管理资源,利用的就是C++构造的对象最终会被对象的析构函数销毁的原则。RAII的做法是使用一个对象,在其构造时获取对应的资源,在对象生命期内控制对资源的访问,使之始终保持有效,最后在对象析构的时候,释放构造时获取的资源。 使用RAII机制的原因 RAII是合理管理资源避免出现内存泄漏的常用方法。那

qq_37535749的博客 5597

C++中的RAII机制详解

主要介绍了C++中的RAII机制详解,RAII是Resource Acquisition Is Initialization的简称,是C++语言的一种管理资源、避免泄漏的惯用法,需要的朋友可以参考下

C++程序设计机制:RAII机制

1、背景 C/C++程序开发中,管理堆上分配的内存容易出错,常见的就是内存泄漏。原则上,只要我们足够仔细,在每一次动态分配内存之后,使用完毕后,手动delete即可释放掉内存,可是这必然会加大我们的工作量以及项目的维护难度。 2、RAII机制原理 RAII,即Resource Acquisition Is Initialization,在初始化中获取资源。 RAII机制,通过在栈上创建临时变量,这样临时变量就接管了堆上内存的控制权,当该临时变量声明周期结束时,则对应的堆上内存自然就被释放了。 3、

技术成就梦想,梦想成就未来。If you try hard enough, it can be. 7490

最新Mamba环境配置教程:从CUDA到causal-conv1d的完整安装流程

本文提供最新Mamba环境配置教程,涵盖从CUDA到causal-conv1d的完整安装流程。针对深度学习领域的长序列处理需求,详细指导如何正确配置CUDA工具链、安装PyTorch及关键依赖causal-conv1d,解决常见报错问题,并验证mamba-ssm集成效果。

bush的博客 418

Silvaco TCAD | 从极化效应到高频开关:GaN HEMT仿真设计与性能验证

本文深入探讨了使用Silvaco TCAD进行GaN HEMT仿真设计与性能验证的关键技术。从极化效应到高频开关特性,详细解析了2DEG形成机制、器件结构设计优化及高频特性仿真技巧,帮助工程师提升GaN HEMT的性能与可靠性。通过实战案例展示了如何通过仿真优化击穿电压和导通电阻,实现开关品质因数的显著提升。

weixin_30872337的博客 484

C++ RAII机制浅谈

RALL机制使得C++程序员能够优雅的释放内存。

树欲静静风不止止的博客 3979

TI AWR2944毫米波雷达开发板开箱:用官方Demo快速上手3D点云与热图生成

本文详细介绍了TI AWR2944毫米波雷达开发板的开箱与实战应用,包括硬件准备、软件开发环境搭建、Demo固件刷写与配置、实时可视化与数据解析等全流程指南。通过官方Demo快速上手3D点云与热图生成,帮助开发者高效掌握毫米波雷达技术在工业检测、智能交通等领域的应用。

weixin_42627853的博客 309

C++的RAII机制

RAII是Resource Acquisition Is Initialization(wiki上面翻译成 “资源获取就是初始化”)的简称,是C++语言的一种管理资源、避免泄漏的惯用法。利用的就是C++构造的对象最终会被销毁的原则。RAII的做法是使用一个对象,在其构造时获取对应的资源,在对象生命期内控制对资源的访问,使之始终保持有效,最后在对象析构的时候,释放构造时获取的资源。

ljy的博客 1240

计算机视觉——多视图几何

多视图几何1.前言1.1 多视图几何概念2. 基本原理2.1 对极几何2.2 基础矩阵2.2.1 基础矩阵推导2.2.2 求解基础矩阵3. 实验过程3.1 实验数据准备3.2 实验代码3.3 实验结果及分析4. 实验中遇到的问题 1.前言 1.1 多视图几何概念 多视图几何是利用在不同视点所拍摄图像间的关系,来研究照相机之间或者特征之间关系的一门科学。 多视图几何(Multiple View ...

RuiMa的博客 7715

28GHz毫米波滤波器设计实战:用SynMatrix快速搞定SIW带通滤波器(附完整参数)

本文详细介绍了如何使用SynMatrix工具链高效设计28GHz SIW带通滤波器,涵盖智能参数预测、多物理场联合优化和加工误差补偿等核心技术。通过实战案例和完整参数模板,帮助射频工程师快速实现毫米波滤波器设计,显著提升工作效率并避免反复迭代。

weixin_29284657的博客 496

【C++】RAII机制

RAII(资源获取即初始化)是一种 C++ 编程范式,其核心思想是将资源的管理(例如内存、文件句柄、网络连接等)绑定到对象的生命周期上,即在对象构造时获取资源,在对象析构时释放资源。这样无论程序是否正常执行或者发生异常,资源都能得到及时而正确的释放,从而避免资源泄漏和其他资源管理问题。

qq_52208569的博客 885

mac搭建ios自动化环境之WebDriverAgent配置

一、WebDriverAgent 1、简单介绍: WebDriverAgent是facebook为苹果公司开发的一款自动化测试工具,github上有下载资源;另外appium安装后也会自动安装自带的WebDriverAgent;可以用自带的,也可以从github下载并替换自带的; 2、不同appium版本自带WebDriverAgent默认路径不同 1)appium 1.10.1之前版本: npm方式安装: /usr/local/lib/node_modules/appium/node_modules/a

qq_30237715的博客 2763

C++RAII机制

什么是RAII? RAII是Resource Acquisition Is Initialization(wiki上面翻译成 “资源获取就是初始化”)的简称,是C++语言的一种管理资源、避免泄漏的惯用法。利用的就是C++构造的对象最终会被销毁的原则。RAII的做法是使用一个对象,在其构造时获取对应的资源,在对象生命期内控制对资源的访问,使之始终保持有效,最后在对象析构的时候,释放构造时获取的资源...

风一样的男子(quinta)的博客 2万+

【C++/嵌入式梳理】bootloader

【C++/嵌入式笔试面试八股】bootloader

Hi 1211

【Zephyr存储专题】09_LittleFs文件系统操作

本文档旨在为开发者介绍Zephyr下Littlef's文件系统相关配置使用指南

zero的博客 3246

C++中的RAII机制

前言 在写C++设计模式——单例模式的时候,在写到实例销毁时,设计的GC类是很巧妙的,而这一巧妙的设计就是根据当对象的生命周期结束时会自动调用其析构函数的,而这一巧妙的设计也是有专业的名词的——RAII。那以下将围绕RAII,全面的讲解RAII的相关知识。 什么是RAII? RAII是Resource Acquisition Is Initialization的简称,是C++语言

wozhengtao的博客 9031

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

CPP杂记——使用RAII机制管理实体资源

起初接触到RAII机制是在使用std中的lock_guard()方法时对于其只需一行的加锁方式感到好奇。 其实所谓RAII就是利用C++中构造的临时对象一定会被析构的原理构造一个临时对象,在构造时获取需要纳入管理的资源,并在其生命周期结束后随析构函数的调用而释放。 要注意的是,生成的RAII风格管理类最好禁用拷贝构造函数和operator=\color{red}{要注意的是,生成的RAII风格...

黑色低级高中生的博客 416

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

《C++ 中 RAII 机制:解决资源泄漏的利器》

RAII 是一种 C++ 编程技术,其核心思想是将资源的获取和初始化绑定在一起,同时将资源的释放和对象的析构绑定在一起。当对象被创建时,资源会被自动获取;当对象的生命周期结束时,析构函数会自动被调用,从而释放资源。这种机制确保了资源的正确管理,避免了手动管理资源时可能出现的错误。RAII 机制是 C++ 中一种非常重要的资源管理技术,它通过将资源的获取和初始化与对象的生命周期绑定在一起,提供了一种优雅且高效的资源管理解决方案。RAII 机制可以避免资源泄漏,简化代码逻辑,提高代码的安全性和可维护性。

yzz19900508的博客 931

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

C++之RAII机制

1.什么是RAII? RAII(Resource Acquisition Is Initialization)机制是Bjarne Stroustrup首先提出的,也称直译为“资源获取就是初始化”,是C++语言的一种管理资源、避免泄漏的机制。 C++标准保证任何情况下,已构造的对象最终会销毁,即它的析构函数最终会被调用。 RAII 机制就是利用了C++的上述特性,在需要获取使用资源RES的...

菜头 2137

【C++ 面试题】RAII 机制

— 资源获取即初始化。把资源的申请与对象的构造绑定;把资源的释放与对象的析构绑定。因此,只要对象的生命周期结束(无论以何种方式),资源一定被安全释放。Stack Unwinding(栈展开)调用已构造对象的析构函数;弹出栈帧;直到找到能处理异常的catch块;若没找到,程序最终调用结束。优点说明✅ 自动释放资源避免内存泄漏✅ 异常安全抛异常也能正确释放✅ 可组合可与 STL 容器、智能指针等结合✅ 可移植适用于任何需要 acquire/release 的资源。

qq_53655497的博客 651

C++11实现模板化(通用化)RAII机制

什么是RAII?RAII(Resource Acquisition Is Initialization),也称直译为“资源获取就是初始化”,是C++语言的一种管理资源、避免泄漏的机制。 C++标准保证任何情况下,已构造的对象最终会销毁,即它的析构函数最终会被调用。 RAII 机制就是利用了C++的上述特性,在需要获取使用资源RES的时候,构造一个临时对象(T),在其构造T时获取资源,在T生命期控

10km的专栏 1万+

C++程序的设计机制3: RAII机制

本文已搬家至【设计技巧】C++中的RAII机制

gnuhpc的专栏 9217
上一篇: 通俗的理解MFC消息机制
下一篇: halcon 基于相关性创建模板
越甲八千
博客等级 码龄11年 2959粉丝 553原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值