纯虚析构函数(C++)

虚析构与纯虚析构解决内存泄漏问题(C++) 虚析构与纯虚析构解决内存泄漏问题 当我们new一个子类的对象,并用父类的指针指向它时,若父类中使用一般的析构函数,则父类指针在析构的时候,不会调用子类中的析构函数,导致子类在堆区开辟的数据则无法释放,造成内存泄漏。 使用虚析构与纯虚析构函数可以解决这一问题。 1、虚析构 父类中使用一般的析构函数时: #include <iostream> using namespace std; class A//父类A { public: A() { cout <&lt 阅读详情

一个纯虚析构函数(Pure Virtual Destructor)。代码:

cpp

virtual ~Product() = 0; // 虚函数

这样写的目的:让 Product 成为一个抽象基类(不能实例化),同时又需要确保派生类对象被正确析构。


一、为什么析构函数要写成虚函数?

先回答“虚”的部分:
如果基类的析构函数不是虚函数,当通过基类指针删除派生类对象时,只会调用基类的析构函数,派生类的析构函数不会被调用,导致派生类资源泄漏。

cpp

Base *p = new Derived();
delete p;  // 如果Base析构不是虚函数,Derived的析构不会被调用 ❌

所以基类析构函数必须声明为 virtual。


二、为什么写成 = 0(纯虚)?

= 0 让析构函数变成纯虚函数,效果是:

  • Product 变成抽象类,不能创建对象:Product p; 编译报错。

  • 但仍然必须实现这个析构函数(没错,纯虚析构函数必须有函数体)。


三、纯虚析构函数的特殊规则

普通纯虚函数可以只有声明,没有实现(派生类必须重写)。
但析构函数不同:编译器在析构派生类对象时,最终会自动调用基类的析构函数。所以即使是纯虚析构函数,也必须提供实现。

正确的写法必须是:

cpp

// Product.h
class Product
{
public:
    Product() {}
    virtual ~Product() = 0;  // 声明为纯虚
};

// Product.cpp
Product::~Product() {}  // 👈 必须有函数体!

四、完整示例说明

cpp

#include <iostream>
using namespace std;

class Product {
public:
    Product() { cout << "Product构造" << endl; }
    virtual ~Product() = 0;  // 纯虚析构
};

Product::~Product() {        // 必须实现!
    cout << "Product析构" << endl;
}

class Book : public Product {
public:
    Book() { cout << "Book构造" << endl; }
    ~Book() { cout << "Book析构" << endl; }
};

int main() {
    Product *p = new Book();
    delete p;  // 输出:Book析构 -> Product析构 ✅
    return 0;
}

输出:

text

Product构造
Book构造
Book析构
Product析构

五、对比:其他写法

写法是否抽象类能否实例化派生类析构是否安全是否需要实现
~Product() {}❌ 否✅ 能✅ 安全(虚函数)需要
virtual ~Product() {}❌ 否✅ 能✅ 安全需要
virtual ~Product() = 0; + 实现✅ 是❌ 不能✅ 安全必须实现
~Product() = 0;(无实现)✅ 是❌ 不能❌ 链接错误缺实现会报错

六、什么时候这样写?

典型场景:你需要一个抽象基类定义接口(比如工厂模式中的 Product),同时这个基类需要做一些通用的清理工作,并且必须确保派生类的析构函数被正确调用。

cpp

// 工厂模式中的抽象产品
class Product {
public:
    virtual void use() = 0;          // 纯虚接口
    virtual ~Product() = 0;          // 保证派生类正确析构 + 抽象类
};
Product::~Product() {}               // 基类清理逻辑

七、一句话总结

virtual ~Product() = 0; 的意思:
让 Product 成为抽象类(不能实例化),同时确保通过基类指针删除派生类对象时,能正确调用派生类和基类的析构函数。
记住:纯虚析构函数必须在类外提供实现。

如果你看到的是 virtual ~Product() {}(没有 = 0),那它只是一个普通的虚析构函数,Product 可以实例化,不是抽象类。

高程 | 多态性(c++) 运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用于不同类型的数据时导致不同的行为。实质就是函数重载。operator是重载关键字。 阅读详情

相关推荐

CentOS7 安装天气分型软件cost733过程详解

cost733是一款天气分型软件,其内置的一些算法可以帮助气象工作者进行天气类型划分等(我也是初学者,仅仅知道一些皮毛),但是网上找到的安装办法比较少,并且总会出现一些报错,试了一晚上,终于将安装办法调通了,希望可以帮助到大家

weixin_62573024的博客 3563

虚析构和纯虚析构函数

5.1 虚析构 5.1.1 virtual ~类名() {} 5.1.2 解决问题: 通过父类指针指向子类对象释放时候不干净导致的问题 5.2 纯虚析构函数 5.2.1 写法 virtual ~类名() = 0 5.2.2 类内声明 类外实现 5.2.3 如果出现了纯虚析构函数,这个类也算抽象类,不可以实例化对象 析构函数 #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<string> using names

Scarlett的博客 1001

基于STM32F103的二维码识别项目——OV7670篇

此系列用于记录做过的项目,这篇文章介绍基于STM32F103的二维码识别项目之OV7670FIFO模块。

beyourself_he的博客 4289

多态 进阶(虚析构,纯虚函数,纯虚析构)

虚函数 纯虚函数 虚析构 纯虚析构(重要) 重写 重载 重定义(了解)

兰天禄的博客 3534

PPO算法详解:基于CartPole-v1的强化学习实现

PPO算法详解:基于CartPole-v1的强化学习实现

m0_54720701的博客 865

《通信工程施工与管理》

制作馈线接头必须使用专用的工具,专用工具包括:馈线切割刀、馈线安全刀、小金属丝毛刷、固定尺寸或大号活动扳手、小号扁锉刀、细齿小手锯、接头扩孔器、3M防水胶或防水接头盒;如图所示,详情如表所示。

2302_78710464的博客 1654

6.4虚析构函数和纯虚析构函数

虚析构函数和纯虚析构函数

qq_52563729的博客 1152

【迁移学习综述】

迁移学习的目标是将某个领域或任务上学习到的知识应用到不同的但相关的领域或问题中。迁移学习的研究来源于一个观测:人类可以将以前的学到的知识应用于解决新的问题,更快的解决问题或取得更好的效果。迁移学习被赋予这样一个任务:从以前的任务当中去学习知识(knowledge)或经验,并应用于新的任务当中。换句话说,迁移学习目的是从一个或多个源任务(source tasks)中抽取知识、经验,然后应用于一个目标领域(target domain)当中去。

afadgas的博客 4321

C++——虚函数和纯虚函数、抽象类、虚析构和纯虚析构

C++虚函数、纯虚函数、虚析构、纯虚析构,其中虚函数的原理为重点

qq_42106610的博客 9358

用Python和NumPy搞定复合材料层合板ABD矩阵计算(附完整代码与避坑指南)

本文详细介绍了如何使用Python和NumPy高效计算复合材料层合板的ABD刚度矩阵,包括单层板刚度计算、偏轴转换和层合板刚度集成。通过完整的代码示例和工程实践技巧,帮助工程师快速构建定制化分析工具,解决航空航天、汽车制造等领域的复合材料力学性能分析问题。特别提供了避坑指南和性能优化策略,确保计算结果的准确性和效率。

weixin_30752699的博客 279

【开发必备插件】iframe嵌套报“拒绝连接请求”的本地解决方法

关键词:iframe 拒绝连接、X-Frame-Options、Chrome 插件、前端调试、Allow X-Frame-Options前几天我在本地项目里调试一个第三方网站的嵌入页面时,遇到了一个非常经典的报错:xxx.com 拒绝了我们的连接请求。熟悉的老前端们一眼就知道——这是。但对于日常开发来说,我们经常需要在本地测试 iframe 嵌套外部页面(比如嵌第三方登录页、支付页、可视化报表系统等)。而线上站点配置了或DENY时,就会直接导致 iframe 加载失败。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 1545

纯虚析构函数

纯虚析构函数和普通纯虚函数的区别在于,纯虚析构函数需要提供函数的实现,而一般纯虚函数不能有实现,这样的原因在于,纯虚析构函数最终需要被调用,以析构基类对象,虽然是抽象类没有实体。而如果不提供该析构函数的实现,将使得在析构过程中,析构无法完成而导致析构异常的问题 Calss A {    public:    A(){}    virtual ~A()=0; } A::~A(){}

7708

Python爬虫实战:全自动采集银行理财产品收益率数据

本文通过Playwright动态爬虫技术,成功实现了对银行理财产品收益率数据的实时采集,并通过 Pandas 数据清洗、SQLite 存储、调度自动化等模块,构建了一个可扩展的银行理财数据抓取系统。理财非儿戏,数据做决策。掌握银行收益信息是我们迈向理性投资的第一步。希望这套工具对你有所帮助!

2201_76125261的博客 1156

虚析构函数(C++)

C++允许将析构函数定义为虚函数,为什么?将基类析构函数定义为虚函数。

qq_36091214的博客 582

深度学习工具包 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")

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

游戏开发之纯虚函数、虚析构函数及抽象类(C++)

游戏开发之纯虚函数、虚析构函数及抽象类(C++) 1.纯虚函数 纯虚函数是一个特殊的函数,在一个类的内部又纯虚函数之后,该类就不可以直接声明为实体类,必须在子类继承该类之后,子类可以间接声明其实体类。 纯虚函数在子类是必须要实现的,否则C++编译器会报错。 纯虚函数的定义语法: virtual 数据类型 函数名(形参列表) = 0; class A { public: //纯虚函数定义语法: //virtual 数据类型 函数名(形参列表) = 0; virtual void Prin

田螺姑娘的博客 561

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

(C++)虚析构函数

基类:Per 继承类:Stu 主函数: Per *p = new Stu; delete p; 如果 ~Per()  //析构函数没有声明为虚函数 则不会调用Stu类的析构函数,只调用~Per() 如果 vritual ~Per()     //虚析构函数 则也会调用Stu类的析构函数。

awutongaxinwande的博客 378

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

C++用纯虚析构函数定义一个抽象类

【代码】C++用纯虚析构函数定义一个抽象类。

追赶时代的博客 476

虚析构函数

//如果基类析构函数不是虚析构函数,派生类的析构函数不会被调用 #define _CRT_SECURE_NO_WARNINGS #include<iostream> using namespace std; class Animal { public: Animal(char *name); void print_name(); virtual void print_color(...

NJU phd 在读。 966

动态多态的实现和虚析构和纯虚析构(c++)

首先需要明确多态性的用途,是为了接口的最大程度复用,以及其定义: 多态性的定义,可以简单地概括为“一个接口,多种方法”,程序在运行时才决定调用的函数,它是面向对象编程领域的核心概念。多态(polymorphism),字面意思多种形状。多态分为静态多态和动态多态。 静态多态是通过重载和模板技术实现,在编译的时候确定。 动态多态通过虚函数和继承关系来实现,执行动态绑定,在运行的时候确定。 定义明确,接下来看看最常见的动态多态的实现思路:对于一组相关的数据类型,抽象出它们之间共同的功能集合,在基类中将共同的功

weixin_67993841的博客 1344

虚析构和纯虚析构(C++)

解决父类无法释放子类的堆区内存问题。 注意:纯虚析构无法实例化 虚析构和纯虚析构 多态使用时,如果子类有对象开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码 解决方式:将父类中的析构函数改为虚析构或者纯虚析构 虚析构和纯虚析构的共性: 可以解决父类指针释放子类对象 都需要有具体的函数实现 虚析构和纯虚析构的区别: 如果是纯虚析构,该类属于抽象类,无法实例化对象 #include<stdio.h> #include <iostream> #include<stri

EIDoradol的博客 292

(C++)多态

1、问题的引出 基类的指针指向派生类对象,在访问函数(基类与派生类的同名函数)时,只能调用基类的函数。 如何才能通过基类指针调用派生类函数? #include <iostream> using namespace std; class Parent { public: void show() { cout<<"this is Parent"<<endl; } }; class Chil...

weixin_53812805的博客 509

面向对象编程:多态性(C++)

面向对象编程:多态性(C++) 文章目录面向对象编程:多态性(C++)一、简介二、类继承层次中对象之间的关系 一、简介 1、介绍:同样的消息给各种不同的对象时,会产生多种形式的结果,这就是多态性。 注: (1)、继承层次中的对象 (2)、消息是重载的函数 (因为重载的函数的签名才会一样,即函数名和类型) 2、多态性能设计和实现更具扩展性的软件系统。 3、多态性的两个底层技术:虚函数和动态绑定 ...

lflcodeplus的博客 2564

c++的类 基类指针数组与虚析构函数(九)

虚析构函数 就是 向派生类传递的析构结构 虚函数 是从顶部向下传递 虚析构函数是从底部向上传递的 基类是顶层 #include <iostream> #include <string> using namespace std; class A{ public: A() = default; A(string s) :s{ s }{} virtual ~A(){ cout << "析构函数A\n"; } // 虚析构函数向下传递 virtual void pri

qq_44698445的博客 557

类(C++)

类基础 结构 访问控制与封装 类内初始值 构造函数 概念 特性 合成的默认构造函数 重载构造函数 构造函数初始化列表 =default =delete 拷贝构造函数 合成拷贝构造函数 拷贝初始化 析构函数 类的成员函数 const成员函数 可变数据成员(mutable) this 返回自身的引用 类的静态成员 声明静态成员 定义静态成员 使用静态成员 ​编辑 标准库move函数 移动 对象移动 移动构造函数 移动赋值运算符 合成的移动操作 继承

(#Д#)ノ~┻━┻(; ̄Д ̄)ノノ⌒○☆゚.*・( ゚Д゚)<!!~~~~~ 1874

(C++)类与对象——多态基础知识

目录一、多态的基本概念二、多态的原理剖析 一、多态的基本概念 #include <string> #include <iostream> using namespace std; /*动态多态的满足条件 1.有继承关系 2.子类中重写父类的虚函数 重写:函数返回值类型 函数名 参数列表 完全一致称为重写 动态多态的使用 父类的指针或者引用, 执行子类对象*/ class Animal { public: virtual void speak() { cout &l

Lemon_CHA的博客 231

学生管理系统(C++)

引言 学习c++后一直想写个学生管理系统,趁假期终于肝出了整个系统,让我对c++的理解更深了一层;写代码时真正体会到了内存操作的困难(想学java),但是通过几个巧妙的方法解决了内存问题,并在n次debug后终于调试出了完整代码,接下来我来介绍一下整个系统; ps:今天太累了,明天再写????; 代码如下: #include <iostream> #include<fstream> #include<cstring> #include<vector> usin

YXXXYX的博客 1万+
上一篇: 一级指针和二级指针的用法、用途、底层原理
下一篇: Meyers‘ Singleton 最优单例(C++)
second60
博客等级 码龄9年 155粉丝 88原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值