返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C#利用Spire.Pdf包实现为PDF添加数字签名
  • 529
分享到

C#利用Spire.Pdf包实现为PDF添加数字签名

2024-04-02 19:04:59 529人浏览 独家记忆
摘要

目录背景简介依赖源码背景 对pdf文档进行数字签名的需求对PDF文档添加水印的需求网上资料版本不一或不全 本文章提到的Spire.Pdf均是使用的Spire.Pdf for .net

背景

  • pdf文档进行数字签名的需求
  • 对PDF文档添加水印的需求
  • 网上资料版本不一或不全

本文章提到的Spire.Pdf均是使用的Spire.Pdf for .net,除此之前还有其他语言的版本,如Spire.Pdf for JAVA;
Spire.Pdf主要用于操作PDF,另外还有Spire.excel、Spire.Doc等
主要介绍了在C#中使用Spire.Pdf组件包对PDF文档进行数字签名、添加水印功能,旨在引导大家快速、轻松的对PDF文档进行数字签名和添加水印功能;

简介

Spire.PDF for .NET 是一款专业的基于.NET平台的PDF文档控制组件。它能够让开发人员在不使用Adobe Acrobat和其他外部控件的情况下,运用.NET 应用程序创建,阅读,编写和操纵PDF 文档。Spire.PDF for .NET 功能丰富,除了基本的功能比如:绘制多种图形,图片,创建窗体字段,插入页眉页脚,输入数据表,自动对大型表格进行分页外,Spire.PDF for .NET还支持PDF数字签名,将html转换成PDF格式,提取PDF文档中的文本信息和图片等,目前Spire.PDF for .NET共有两个版本,一个是免费版本一个是付费版本,免费版本如果只是处理简单的pdf是没问题的,但是如果涉及到输出为pdf则会只显示前10页,第十一页则是预定的购买页介绍,我这里主要是对PDF文档的数字签名和水印,所以不涉及输出pdf;

依赖

本文示例代码依赖于Spire.Pdf,可以在项目中使用NuGet程序包引入。

源码

核心代码

public class DigitalSignature
    {
        /// <summary>
        /// 页顶部红色警告字样覆盖白色图片Base64.
        /// </summary>
        private const string WatermarkCoverBase64 = "/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKCwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCABHAycDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBGCICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZMQKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAWEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSelkU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6GoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAaiRAxEAPwD9U6KKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//Z";

        /// <summary>
        /// 构造函数.
        /// </summary>
        /// <param name="waitSignFile">待签名文件.</param>
        /// <param name="imageSign">签名图片.</param>
        /// <param name="pfx">签名证书.</param>
        /// <param name="pfxPwd">签名证书密码.</param>
        public DigitalSignature(byte[] waitSignFile, byte[] imageSign, byte[] pfx, string pfxPwd)
        {
            this.WaitSignFile = waitSignFile;
            this.ImageSign = imageSign;
            this.Pfx = pfx;
            this.PfxPwd = pfxPwd;
        }

        /// <summary>
        /// 构造函数.
        /// </summary>
        /// <param name="waitSignFile">待签名文件.</param>
        /// <param name="charactersSign">签名文字.</param>
        /// <param name="signRightLeftWidth">签名右向左宽度.</param>
        /// <param name="signBottomUpHeight">签名低向上高度.</param>
        /// <param name="pfx">签名证书.</param>
        /// <param name="pfxPwd">签名证书密码.</param>
        public DigitalSignature(byte[] waitSignFile, string charactersSign, float signRightLeftWidth, float signBottomUpHeight, byte[] pfx, string pfxPwd)
        {
            this.WaitSignFile = waitSignFile;
            this.CharactersSign = charactersSign;
            this.SignRightLeftWidth = signRightLeftWidth;
            this.SignBottomUpHeight = signBottomUpHeight;
            this.Pfx = pfx;
            this.PfxPwd = pfxPwd;
        }

        /// <summary>
        /// 构造函数.
        /// </summary>
        /// <param name="waitSignFile">待签名文件.</param>
        /// <param name="imageSign">签名图片.</param>
        /// <param name="charactersSign">签名文字.</param>
        /// <param name="pfx">签名证书.</param>
        /// <param name="pfxPwd">签名证书密码.</param>
        public DigitalSignature(byte[] waitSignFile, byte[] imageSign, string charactersSign, byte[] pfx, string pfxPwd)
        {
            this.WaitSignFile = waitSignFile;
            this.ImageSign = imageSign;
            this.CharactersSign = charactersSign;
            this.Pfx = pfx;
            this.PfxPwd = pfxPwd;
        }

        /// <summary>
        /// Gets or sets 待签名文件.
        /// </summary>
        public byte[] WaitSignFile { get; set; }

        /// <summary>
        /// Gets or sets 图签名.
        /// </summary>
        public byte[] ImageSign { get; set; }

        /// <summary>
        /// Gets or sets 文字签名.
        /// </summary>
        public string CharactersSign { get; set; }

        /// <summary>
        /// Gets or sets 签名右向左的宽度.
        /// </summary>
        public float? SignRightLeftWidth { get; set; }

        /// <summary>
        /// Gets or sets 签名顶向上高度.
        /// </summary>
        public float? SignBottomUpHeight { get; set; }

        /// <summary>
        /// Gets or sets 签名索引页面(不指定默认所有页进行签名).
        /// </summary>
        public int? SignIndexPages { get; set; }

        /// <summary>
        /// Gets or sets Pfx证书.
        /// </summary>
        public byte[] Pfx { get; set; }

        /// <summary>
        /// Gets or sets Pfx证书密码.
        /// </summary>
        public string PfxPwd { get; set; }

        public Stream Signature()
        {
            ///加载PDF文档
            PdfDocument pdf = new PdfDocument();
            pdf.LoadFromBytes(this.WaitSignFile);

            if (pdf?.Pages?.Count <= 0)
            {
                throw new Exception("文件有误");
            }

            X509Certificate2 x509 = new X509Certificate2(this.Pfx, this.PfxPwd);
            PdfOrdinarySignatureMaker signatureMaker = new PdfOrdinarySignatureMaker(pdf, x509);

            var appearance = new PdfCustomSignatureAppearance(this.CharactersSign, this.ImageSign, this.SignRightLeftWidth, this.SignBottomUpHeight);
            IPdfSignatureAppearance signatureAppearance = appearance;

            // 绘画白底图片
            PdfRubberStampAnnotation logoStamp = new PdfRubberStampAnnotation(new RectangleF(new PointF(0, 0), new SizeF(350, 22)));
            PdfAppearance logoApprearance = new PdfAppearance(logoStamp);
            //var logoPath = AppDomain.CurrentDomain.BaseDirectory + "\\white.jpg";
            byte[] byt = Convert.FromBase64String(WatermarkCoverBase64);
            Stream streamByLogo = new MemoryStream(byt);
            PdfImage image = PdfImage.FromStream(streamByLogo);
            PdfTemplate template = new PdfTemplate(350, 22);
            template.Graphics.DrawImage(image, 0, 0);
            logoApprearance.NORMal = template;
            logoStamp.Appearance = logoApprearance;

            if (this.SignIndexPages.HasValue)
            {
                if (this.SignIndexPages.Value < 0 || this.SignIndexPages.Value > pdf?.Pages?.Count)
                {
                    throw new Exception("签名索引页有误");
                }

                var page = pdf.Pages[this.SignIndexPages.Value];

                // 添加白底图片覆盖页面顶部印记
                page.AnnotationsWidget.Add(logoStamp);

                // 在页面中的指定位置添加可视化签名
                signatureMaker.MakeSignature("signName_", page, page.ActualSize.Width - appearance.SignRightLeftWidth, page.ActualSize.Height - appearance.SignBottomUpHeight, appearance.SignRightLeftWidth, appearance.SignBottomUpHeight, signatureAppearance);
            }
            else
            {
                foreach (PdfPageBase page in pdf.Pages)
                {
                    // 添加白底图片覆盖页面顶部印记
                    page.AnnotationsWidget.Add(logoStamp);

                    // 在页面中的指定位置添加可视化签名
                    signatureMaker.MakeSignature("signName_", page, page.ActualSize.Width - appearance.SignRightLeftWidth, page.ActualSize.Height - appearance.SignBottomUpHeight, appearance.SignRightLeftWidth, appearance.SignBottomUpHeight, signatureAppearance);
                }
            }

            MemoryStream stream = new MemoryStream();
            pdf.SaveToStream(stream, FileFormat.PDF);
            pdf.Close();
            return stream;
        }

        /// <summary>
        /// 使用第三方插件 =》 去除  Evaluation Warning : The document was created with Spire.PDF for .NET.
        /// </summary>
        /// <param name="sourcePdfs">原文件地址</param>
        //private static MemoryStream ClearPdfFilesFirstPage(MemoryStream sourcePdf)
        //{
        //    iTextSharp.text.pdf.PdfReader reader = null;
        //    iTextSharp.text.Document document = new iTextSharp.text.Document();
        //    iTextSharp.text.pdf.PdfImportedPage page = null;
        //    iTextSharp.text.pdf.PdfCopy pdfCpy = null;
        //    int n = 0;
        //    reader = new iTextSharp.text.pdf.PdfReader(sourcePdf);
        //    reader.ConsolidateNamedDestinations();
        //    n = reader.NumberOfPages;
        //    document = new iTextSharp.text.Document(reader.GetPageSizeWithRotation(1));
        //    MemoryStream memoryStream = new MemoryStream();
        //    pdfCpy = new iTextSharp.text.pdf.PdfCopy(document, memoryStream);
        //    document.Open();
        //    for (int j = 2; j <= n; j++)
        //    {
        //        page = pdfCpy.GetImportedPage(reader, j);
        //        pdfCpy.AddPage(page);

        //    }
        //    reader.Close();
        //    document.Close();
        //    return memoryStream;
        //}
    }


    public class PdfCustomSignatureAppearance : IPdfSignatureAppearance
    {
        public PdfCustomSignatureAppearance(string charactersSign, byte[] sign, float? signRightLeftWidth, float? signBottomUpHeight)
        {
            this.CharactersSign = charactersSign;

            if (sign != null && sign.Length > 0)
            {
                this.Sign = sign;
                MemoryStream ms = new MemoryStream(sign);
                var image = System.Drawing.Image.FromStream(ms);
                if (!signRightLeftWidth.HasValue)
                {
                    signRightLeftWidth = image.Width;
                }

                if (!signBottomUpHeight.HasValue)
                {
                    signBottomUpHeight = image.Height;
                }
            }

            this.SignRightLeftWidth = signRightLeftWidth.Value;
            this.SignBottomUpHeight = signBottomUpHeight.Value;
        }

        /// <summary>
        /// Gets or sets 签名.
        /// </summary>
        public byte[] Sign { get; set; }

        /// <summary>
        /// Gets or sets 签名右向左的宽度.
        /// </summary>
        public float SignRightLeftWidth { get; set; }

        /// <summary>
        /// Gets or sets 签名顶向上高度.
        /// </summary>
        public float SignBottomUpHeight { get; set; }

        /// <summary>
        /// Gets or sets 文字签名.
        /// </summary>
        public string CharactersSign { get; set; }

        public void Generate(Pdfcanvas g)
        {
            if (!string.IsNullOrWhiteSpace(CharactersSign))
            {
                float fontSize = 15;
                var font = new System.Drawing.Font("Arial", fontSize);
                PdfTrueTypeFont fontByPdf = new PdfTrueTypeFont(font, true);
                g.DrawString(CharactersSign, fontByPdf, PdfBrushes.Black, new PointF(0, 0));
            }

            if (this.Sign != null && this.Sign.Length > 0)
            {
                Stream stream = new MemoryStream(this.Sign);
                g.DrawImage(Spire.Pdf.Graphics.PdfImage.FromStream(stream), new PointF(20, 20));
            }
        }
    }

调用实现

static void Main(string[] args)
        {

            

            var fileCert = System.Environment.CurrentDirectory + "\\Cert\\";
            var file = System.Environment.CurrentDirectory + "\\File\\";
            var filePath = file + "dome.pdf";
            var newFilePath = file + $"dome_{DateTime.Now.ToString("yyyyMMddHHmmss")}.pdf";
            var pfxFilePath = fileCert + "edd9386229324d969692dcabf97ac095dpps.fun.pfx";
            var pfxFilePwd = "ABCD123456";
            var signFilePath = file + "sign.png";

            // 数字签名
            var digitalSignature = new DigitalSignature(
                File2Bytes(filePath),
                File2Bytes(signFilePath),
                "Sign Here:",
                File2Bytes(pfxFilePath),
                pfxFilePwd
                );
            var stream = digitalSignature.Signature();

            // 保存签名后的文件
            using (var fileStream = File.Create(newFilePath))
            {
                stream.Seek(0, SeekOrigin.Begin);
                stream.CopyTo(fileStream);
            }

            Console.WriteLine("OK");
            Console.ReadLine();
        }

        /// <summary>
        /// 将文件转换为byte数组
        /// </summary>
        /// <param name="path">文件地址</param>
        /// <returns>转换后的byte数组</returns>
        public static byte[] File2Bytes(string path)
        {
            if (!System.IO.File.Exists(path))
            {
                return new byte[0];
            }

            FileInfo fi = new FileInfo(path);
            byte[] buff = new byte[fi.Length];

            FileStream fs = fi.OpenRead();
            fs.Read(buff, 0, Convert.ToInt32(fs.Length));
            fs.Close();

            return buff;
        }

源码下载:https://GitHub.com/daileass/PDFDigitalSignatureBySelfSignedCertificate

到此这篇关于C#利用Spire.Pdf包实现为PDF添加数字签名的文章就介绍到这了,更多相关C# PDF添加数字签名内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C#利用Spire.Pdf包实现为PDF添加数字签名

本文链接: https://lsjlt.com/news/166502.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C#利用Spire.Pdf包实现为PDF添加数字签名
    目录背景简介依赖源码背景 对PDF文档进行数字签名的需求对PDF文档添加水印的需求网上资料版本不一或不全 本文章提到的Spire.Pdf均是使用的Spire.Pdf for .NET...
    99+
    2024-04-02
  • 怎么用Java实现添加、验证PDF数字签名
    这篇文章主要讲解了“怎么用Java实现添加、验证PDF数字签名”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么用Java实现添加、验证PDF数字签名”吧!目录Jar文件获取及导入方法:在设...
    99+
    2023-06-20
  • C#和vb.net实现PDF 添加可视化和不可见数字签名
    目录1. 在VS程序中通过Nuget安装 Spire.PDF for .NET 版本7.8.2,安装步骤如下:2.在VS程序中添加如下代码添加数字签名2.1 添加可视化数字签名2.2...
    99+
    2024-04-02
  • C#如何实现PDF签名时添加时间戳
    这篇文章给大家分享的是有关C#如何实现PDF签名时添加时间戳的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、程序运行环境编译环境:Visual Studio/.NetFramework 4.8所需测试文件:PD...
    99+
    2023-06-15
  • Java实现添加、验证PDF数字签名的方法示例
    目录Jar文件获取及导入方法:在设置文档内容保护的方法中,除了对文档加密、添加水印外,应用数字签名也是一种有效防伪手段。数字签名的文件比较容易验证,并且具有较高的权威性和可信度。在P...
    99+
    2024-04-02
  • C#中怎么给PDF 添加可视化和不可见数字签名
    这期内容当中小编将会给大家带来有关C#中怎么给PDF 添加可视化和不可见数字签名,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。1. 在VS程序中通过Nuget安装 Spire.PDF for .NET 版...
    99+
    2023-06-20
  • PHP 对PDF文件实现数字签名
    PHP通过TCPDF库对生成的PDF文件进行数字签名。 效果如下: 这个是因为签名证书不在可信任证书列表中。 目录 准备数字证书 1.申请数字证书 2.自签名证书 安装TCPDF 证书签名 设置证书路径 设置证书信息 设置文档签名...
    99+
    2023-08-31
    pdf PHP 数字签名
  • C#实现PDF签名时添加时间戳的2种方法(附VB.NET代码)
    在PDF添加签名时,支持添加可信时间戳来保证文档的法律效应。本文,将通过C#程序代码介绍如何添加可信时间戳,可通过2种方法来实现。文中附上VB.NET代码,有需可供参考。 一、程序运...
    99+
    2024-04-02
  • 利用C#/VB.NET实现将PDF转为Word
    目录将 PDF 转换为固定布局的 Doc/Docx 文档完整代码将 PDF 转换为流动形态的 Doc/Docx 文档完整代码效果图众所周知,PDF 文档支持特长文件,集成度和安全可靠...
    99+
    2022-12-19
    C# PDF转Word C# PDF Word
  • 使用Java怎么添加数字签名到excel
    使用Java怎么添加数字签名到excel?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。1. 添加签名import com.spire.xls.*;import&nbs...
    99+
    2023-06-14
  • 利用Java实现在PDF中添加工具提示
    目录导入jar包添加工具提示ToolTip本文,将介绍如何通过Java后端程序代码在PDF中创建工具提示。添加工具提示后,当鼠标悬停在页面上的元素时,将显示工具提示内容。 导入jar...
    99+
    2024-04-02
  • Android为应用添加数字角标的简单实现
    角标,英语是badge,也就是“徽章,像章,奖章; 象征,标记”的意思。 效果图 可以看到图中的环信单聊这个app右上角的红色的圆圈,里面有6这个数字的,就...
    99+
    2022-06-06
    Android
  • Vue使用pdf-lib实现为文件流添加水印并预览
    目录1. 安装 2. 引入 3. 添加水印使用 3.1 添加文本水印3.2 添加图片文本3.3 封装previewPdf.js3.4 调用使用 ...
    99+
    2023-03-15
    Vue实现文件流添加水印 Vue文件添加水印 Vue添加水印
  • Vue怎么使用pdf-lib实现为文件流添加水印并预览
    今天小编给大家分享一下Vue怎么使用pdf-lib实现为文件流添加水印并预览的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。首...
    99+
    2023-07-05
  • 利用C语言实现猜数字小游戏
    本文实例为大家分享了C语言实现猜数字小游戏的具体代码,供大家参考,具体内容如下 实现猜数字的游戏: 要用程序完成以下几步: 1、电脑自动生成随机数(1到100之间的数字) 2、玩家输...
    99+
    2024-04-02
  • 如何利用PHP7的匿名函数和闭包实现更加灵活的逻辑封装?
    如何利用PHP7的匿名函数和闭包实现更加灵活的逻辑封装?在PHP7中,匿名函数和闭包是非常强大的特性,它们可以帮助我们实现更加灵活和复用性高的代码封装。本文将介绍如何使用PHP7的匿名函数和闭包来实现这些功能,并提供具体的代码示例。闭包是一...
    99+
    2023-10-22
    PHP 闭包 匿名函数 灵活 逻辑封装。
  • 如何利用PHP7的匿名函数和闭包实现更加灵活的代码逻辑?
    如何利用PHP7的匿名函数和闭包实现更加灵活的代码逻辑?随着PHP7的发布,匿名函数和闭包成为了PHP开发中的重要特性。匿名函数允许我们在代码中直接定义并使用函数,而闭包则可以将函数作为变量进行传递和存储。通过灵活地使用匿名函数和闭包,我们...
    99+
    2023-10-22
    PHP 闭包 匿名函数
  • 如何利用C语言实现猜数字小游戏
    这篇文章主要讲解了“如何利用C语言实现猜数字小游戏”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何利用C语言实现猜数字小游戏”吧!实现猜数字的游戏:要用程序完成以下几步:电脑自动生成随机数...
    99+
    2023-06-20
  • C++中怎么利用explicit关键字实现构造函数
    这篇文章给大家介绍C++中怎么利用explicit关键字实现构造函数,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。如果C++类的构造函数有一个参数,那么在编译的时候就会有一个缺省的转换操作:将该构造函数对应数据类型的数...
    99+
    2023-06-17
  • 如何利用PHP7的匿名函数和闭包实现更加灵活的代码逻辑处理?
    如何利用PHP7的匿名函数和闭包实现更加灵活的代码逻辑处理?在PHP7之前,我们经常使用函数来封装一段特定的逻辑,然后在代码中调用这些函数来实现特定的功能。然而,有时候我们可能需要在代码中定义一些临时的逻辑块,这些逻辑块没有必要创建一个独立...
    99+
    2023-10-22
    闭包 匿名函数 灵活编程
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作