Boost 关于 shared_ptr 的学习心得

boost::shared_ptr的线程安全 官方文档的说明 shared_ptr objects offer the same level ofthread safety as built-in types. A shared_ptr instance can be "read"(accessed using only const operations) simultaneously by multiple threads.Differe 阅读详情

今天学习了boost 的智能指针中的shared_ptr,感觉收获颇多,现在就写下来,一则作为学习笔记,二则与大家分享我的学习心得

shared_ptr智能指针我想大家如果看过《C++Primer》第四版(16.5 A generic handle class 一个泛型句柄)的话,应该了解作者构造了一个通过引用计数的方法来管理指针的,

没错shared_ptr 同样是这样实现的,首先先看一下书中的实现:


看完上面的代码我想你应该了解智能指针是如何工作的了吧,看过书本的可以当做一次复习;

对于shard_ptr的结构如何使用我想我不用做过多介绍,看一下头文件再结合文档和网上的一些资料应该很快就明白

下面我展示一下shared_ptr的一个用法:

#include <iostream>
#include "boost/shared_ptr.hpp"
using namespace std;
using namespace boost;
class A
{
	public:
	A(){}
    virtual  void mem_func() = 0;
   protected:
   virtual ~A()
   {
      cout<<"A's dector\n";
   }

	private:

};

class B:public A
{
	public:
	B(){}
	virtual void mem_func()
	{
	   cout<<"I'm mem_fun\n";
	}

};
shared_ptr<A> create()
{
   return shared_ptr<A>(new B);
}
int main()
{
       shared_ptr<A> sp = create();
       sp->mem_func();
      return 0;
}

请注意,上面的代码,A的析构函数被定义为protect,而它在程序结束时候被调用了,这个就是我要将的地方了,我们通过源码来分析一下

首先shared_ptr在内部有两个私有成员:

    T * px;                     // contained pointer
    boost::detail::shared_count pn;    // reference counter

其中 px是原生的指针,也就是 new B 得到的指针,但是他是A * 类型的,shared_ptr通过它来快速访问内存,shared_ptr重载* , ->来让用户像使用原生指针一样来使用,

但是在删除这块内存时,shared_ptr不是直接这样 delete px的,因为~A 是protect,这样释放内存会报错,你可是测试一下的代码就知道了

A * pa = new B;

delete pa;

编译器会报错如:

而你这样定义 A  a同样也编译不过,但是前面的代码明明调用了基类A 的析构函数 打印出了 A‘ dector,不急,往下看pn 这个变量

 pn 这个东东就大有来头了,要完全弄懂,我想我还没那能力,里面涉及到了一些平台相关的知识,我只讲为何会跳用了~A;

其实跟踪pn 可以发现它是:shared_count 类型,它保存一个计数值,也就是如C++Primer中的那个 user ,但是它还保存有一个指针

就是在构造shared_ptr的时候传就去的那个new B,注意是B *类型的指针,px保存的是A* 基类的指针,当pn 的计数值为0的是后就会

delete这个指针,可以看一下shared_ptr的一个构造函数你就会明白它是如何工作的了:

  template<class T>

class shared_ptr{

.............

public:

..........

    template<class Y>
    explicit shared_ptr( Y * p ): px( p ), pn( p ) // Y must be complete
    {
        boost::detail::sp_enable_shared_from_this( this, p, p );
    }

...........

private:

    T * px;                     // contained pointer
    boost::detail::shared_count pn;    // reference counter

};

请注意 在 shared_ptr<A>(new B)中,模板类型 T *是 一个 A * , shared_ptr调用的是一个模板构造函数shared_ptr( Y * p )中的Y* 是 B*,而px(p)

等价于 A* px = B* p ,而对于pn,下面是我从源代码里面复制出来的一个pn的构造构造函数头

    template<class Y> explicit shared_count( Y * p ): pi_( 0 )
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
        , id_(shared_count_id)

可以看到pn也是一个模板,传递过来的 Y * p 就是 就是 shared_ptr<A>(new B)中的new B 了,当计数器为0是就会析构掉这个B* 指针,所以可以知道

其实px与pn内保持的指针类型是不一样的,px 的是A* 而 pn的是 A 的子类 B 的指针,这样       B* pb = new B;    delete pb;是妹问题的。

对于pn 里面复杂的实现我暂时还没能完全理解,有时间再慢慢研究,感兴趣的可以自己去看源代码


全文完!

Boost.shared_ptr陷阱 条款1:不要把一个原生指针给多个shared_ptr管理int* ptr = new int;shared_ptr&lt;int&gt; p1(ptr);shared_ptr&lt;int&gt; p2(ptr); //logic errorptr对象被删除了2次这种问题比喻成“二龙治水”,在原生指针中也同样可能发生。 条款2:不要把this指针给shared_ptrclass Test{publ... 阅读详情

相关推荐

Boost库简单运用——shared_ptr

Boost库简单运用——shared_ptr概述​ 在C++项目中,内存管理的问题一直是个大问题,也是个很常见的问题。项目交由经验不足的程序员来编写维护,常出现内存泄漏、访问非法内存之类的问题,资历较老的程序员也不可避免会出错。所幸STL与Boost都为我们提供了管理动态内存的工具,我们只要如寻常指针一般使用即可,无需担心以往会出现的内存管理上的问题了。这里就先介绍一个shared_ptr,就功

oYinGui1 1345

Boost库基础-智能指针(shared_ptr)

shared_ptr shared_ptr与scoped_ptr同样是用于管理new动态分配对象的智能指针,它们都重载了 *和->操作符,提供显示bool类型转换以判断指针的有效性,get()可以得到原始指针,并且没有提供指针算术操作,也不能管理new[ ] 产生的动态数组指针。 例: shared_ptr<int> spi(new int); //解引用 *spi...

希望能帮助大家,希望大家多多支持,你们的支持是我前进的动力。 2283

【BOOST C++指针专题03】共享指针boost::shared_ptr

boost::shared_ptr是另一个智能指针,与 boost::scoped_ptr有很大不同,本文阐述这种区别。

gongdiwudu的专栏 6410

boost shared_ptr基本用法介绍

一、介绍 share_ptr包装了new操作符在堆上分配的动态对象,但他实现的是计数型的智能指针,share_ptr早期的名字就是counter_ptr,可以自由拷贝和赋值,在任意的地方共享它,当没有代码使用(引用计数为0时)它才删除被包装的动态分配的对象。share_ptr也可以安全地放到标准容器中,是在STL容器中存储指针最标准的解法。 template<class T> class shared_ptr { public: typedef T element_type; //

weixin_41176628的博客 4264

Claude Skills 深度讲解

阶段 1:Function Call(2023)├─ 大模型可以调用外部工具├─ 问题:缺乏对任务的深度理解└─ 局限:工具调用简单线性阶段 2:MCP 上下文工程(2024)├─ 大模型有了更丰富的上下文和工具├─ 问题:仍然需要手动编写复杂的 Prompt└─ 局限:每次对话都需要重新加载上下文阶段 3:Claude Skills(2025)├─ 大模型有了「能力模块」的概念├─ 可以动态加载、组合、执行专门的工作流├─ 真正实现了「知识的模块化和复用」

u013134676的博客 1464

PSM-DID实战指南:Stata代码解析与案例应用

本文详细解析PSM-DID方法在Stata中的实战应用,从理论到代码实现全面覆盖。通过倾向得分匹配(PSM)和双重差分(DID)的结合,有效解决政策评估中的选择偏差问题。文章提供完整的Stata命令代码、样例数据处理技巧和案例应用,帮助研究者准确评估政策效果。

vulkan6gpu的博客 792

Boost开发指南-3.4shared_ptr

public ://内部类型定义 shared_ptr();//构造函数 template < class Y > explicit shared_ptr(Y * p);//析构函数 shared_ptr(shared_ptr const & r);//拷贝构造 shared_ptr & operator =(shared_ptr const & r);

qq_36314864的博客 815

HBuilderx 坑 之前没问题 改了几行代码 小程序上传报分包大小超过限制

Error: 分包大小超过限制,main package source size 4199KB exceed max limit 2MB [20221213 10:08:06][wx432abdb518bdc1eb]下面的我提示是都没超过2M,却提示我超过限制,代码改了不到20行吧,之前是正常上传的.....,比如这类,要压缩的,前提是没压缩过的,但是我肯定提交的时候是压缩的,没勾选此项的要注意,如果本文解决了你的困扰 来波666不为过吧!

爱就码上行动,奔赴热爱,追光而行。愿你带着从容与热爱,拥抱每一天的惊喜与美好 5219

boost::shared_ptr 分析与实现

boost::shared_ptr 分析与实现、 boost::shared_ptr 分析与实现 /************************************************************ * file: shared_ptr * * desc: 本文将对boost::shared_ptr作一详细的介绍。 本文介绍的不是用法,而是 * 智能指针的原理,结构以及boost对其的实现. 最后还会给出一个简化了的实现。 * * author: whiteear * date..

qq_35886593的博客 1146

深入解析DDR5 RFM机制:从JESD79-5标准到硬件实现

本文深入解析了DDR5内存标准中的关键机制——RFM(Refresh Management)。文章从JESD79-5标准出发,详细阐述了RFM如何通过RAA计数器实现从被动定时到主动响应的智能刷新管理,并探讨了其硬件实现细节、命令调度挑战及系统级设计考量,为芯片设计工程师优化DDR5内存子系统性能与可靠性提供了实践指导。

fff88的博客 489

金融科技数据源

数字金融开放研究平台

平平淡淡,戒急用忍,一生学闭嘴。 1758

boost::shared_ptr的使用方法

1. boost::shared_ptr的用法  下面用一个简单的例子说明shared_ptr的用法:   #include #include class A { public: void print() { printf("class A print!\n"); } }; int main(int argc, char **argv) {

鱼思故渊的专栏 2万+

Librepilot _64位window10环境下的搭建及一些坑的解决办法

  刚入IT行业的小菜鸟,在window上折腾了四天的librepilot地面控制站的搭建,想着这么辛苦不能白费了,看网上相关资料少得可怜,唯一一个详细教程还是在32位环境下,一大堆坑,所以把自己的经验写下来,供大家一起参考。 参考的原文是:https://www.cnblogs.com/jasonchan1202/p/7809937.html的博客,但是执行下来才发现这个博客对64位系统极其不...

weixin_41426339的博客 2727

Boost智能指针——shared_ptr

Boost智能指针——shared_ptr 文章目录Boost智能指针——shared_ptr引言内存管理机制 引言 boost::scoped_ptr虽然简单易用,但它不能共享所有权的特性却大大限制了其使用范围,而boost::shared_ptr可以解决这一局限。顾名思义,boost::shared_ptr是可以共享所有权的智能指针,首先让我们通过一个例子看看它的基本用法: #includ...

老码农 1万+

【LOGO动态替换】记录一次关于LOGO动态替换引发的uboot代码分析及其实现

文章目录1.前言2.实现2.1 新增logo分区2.2 制作logo分区镜像2.2.1 查看logo.bmp和logo_kernel.bmp的文件大小。2.2.2 按规则将bmp写入logo.img3.分析3.1 uboot的启动分析3.2 uboot bmp load 显示部分3.2.1 rockchip_show_logo3.2.2 load_bmp_logo3.2.3 load_bmp_logo3.3 uboot bmp read部分3.3.1 read_logo_bmps3.3.1 read_bmp

wang 恒 的博客 1213

【FPGA教程案例87】加解密1——基于FPGA的AES加解密算法verilog实现

DES已走到了它生命的尽头。56比特密钥实在太小,虽然三重DES可以解决密钥长度的问题,但是DES的设计主要针对硬件实现,而今在许多领域,需要用软件方法来实现它,在这种情况下,它的效率相对较低。1997年4月15日美国国家标准和技术研究所(NIST)发起征集AES(Advanced Encryption Standard)算法的活动,并成立了AES工作组。目的是为了确定一个非保密的、公开披露的、全球免费使用的加密算法,用于保护下一世纪政府的敏感信息。这里,我们对AES的基本原理进行介绍:

FPGA/MATLAB学习教程/源码/项目合作开发 2546

c++ boost shared_ptr的使用

介绍 本文主要就是一些对boost::shared_ptr的一些翻译和个人见解,主要来源还是boost官网。 share_ptr模板类储存一个动态的分配对象,一般使用c++的new表达式。这个对象的指针会在最后一次shared_ptr析构的时候或者是reset的时候删除掉。一般的用法如下:shared_ptr<X> p1( new X ); shared_ptr<void>...

└┼﹡keep it simple,stupid■┐*… 1283

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

boost::shared_ptr内部结构

本文是从过去自己的一篇博客中修改而来。因为年代久了,这篇博客的图片被优快云升级搞丢了。所以现在重新绘制了结构图。老文位置:http://blog.youkuaiyun.com/sheismylife/article/details/1694939shared_ptr    shared_ptr源自于著名的boost库,智能指针自从Scott Meyers在其作品>首次提出并给出一个示范版本后得到了很大的发展

Dean Chen的专栏 8372

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

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

智能指针tr1::shared_ptr、boost::shared_ptr使用

对于tr1::shared_ptr在安装vs同时会自带安装,但是版本较低的不存在。而boost作为tr1的实现品,包含 “Algorithms Broken Compiler Workarounds Concurrent Programming Containers Correctness and Testing Data Structures Domain Specific Fu

younghz 5063

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

boost shared_ptr的小技巧

class A{public: virtual void print() = 0;protected: ~A() { cout << "A destroyed..." << endl; }};class B : public A{public: void print() { cout << "B::print..." << endl;

白云哥 3751

Boost库之shared_ptr应用

概解:      shared_ptr非常有价值、非常重要、非常有用!      shared_ptr是一个最像指针的"智能指针",是boost::smart_ptr库中最有价值、最重要的组成部分,也是最有用的,Boost库中许多组件--甚至还包括其他一些领域的智能指针都使用了shared_ptr。      shared_ptr与scoped_ptr一样包装了new操作符在堆上分配的动态对

hlj_include的博客 861

boost shared ptr的使用方法

boost shared ptr的使用方法

qq_44910516的博客 216

boost::shared_ptr指针设置NULL的方法

在使用boost::shared_ptr的时候,有时候想将指针置为NULL。一般地,我们可以向传统指针那样,直接将NULL赋值给指针,也可以调用boos::shared_ptr的reset()方法,将指针重置,也就是设置为NULL,下面是具体的测试代码: /* * @,@Author: ,: your name * @,@Date: ,: 2020-12-09 09:25:03 * @,@LastEditTime: ,: 2020-12-29 10:28:01 * @,@LastEditors.

jinking01的专栏 3961

boost/shared_ptr 用法总结

<br />几乎所有稍微复杂点的程序都需要某种形式的引用计数智能指针。这些智能指针让我们不再需要为了控制被两个或多个对象共享的对象的生存期而编写复杂的逻辑。当引用计费降为零,没有对象再需要这个共享的对象,这个对象就自动被销毁了。引用计数智能指针可以分为插入式(intrusive)和非插入式(non-intrusive)两类。前者要求它所管理的类提供明确的函数或数据成员用于管理引用计数。这意味着在类的设计时就必须预见到它将与一个插入式的引用计数智能指针一起工作,或者重新设计它。非插入式的引用计数智能指针对它所

ldd909的专栏 1080
上一篇: C/C++中的日期和时间
下一篇: C++ 简单文件读写
hellosijian
博客等级 码龄16年 35粉丝 23原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值