自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(407)
  • 收藏
  • 关注

原创 CMake:相关概念与使用入门(一)

Cmake是一个项目构建工具,并且是跨平台的。关于项目构建我们所熟知的有Makefile,然后通过make命令进行项目的构建,并且大多数是IDE都继承了make,比如:VS的nmake,Linux下的GNU make、Qt的qmake等。如果自己手动写makefile,会发现makefile通常依赖当前的编译平台,并且makefile的工作量比较大,解决依赖关系也容易出错。

2024-04-25 21:46:17 181

原创 C++高级特性:异常概念与处理机制(十四)

异常被抛出后,从进入try块起到异常抛出前(throw),这期间在栈上创建的所有对象都会被自动析构。这种情况就可以考虑使用多态的特性了,定义基类异常,所有可能的异常都继承基类异常,而捕获时只需要捕获基类异常即可。异常:是指在程序运行的过程中发生的一些异常事件(如:除数为0,数组下标越界,栈溢出,访问非法内存等)推荐使用抛出引用类型的异常处理,不会进行拷贝和手动分配堆区空间的问题,不会造成内存泄漏和性能负担。runtime_error子类。logic_error子类。

2024-04-24 10:28:16 639

原创 C++高级特性:虚函数与多态的实现原理(十三)

如果一个类存在virtual关键字函数或者继承的基类中存在virtual关键字的函数,那么该类的就会存在vptr和一个vtable。空类的大小为1字节,而存在虚函数(虚析构函数或其他虚函数)那么就会为该类生成一个vptr虚函数表指针和一个vtable虚函数表。其次调用本类的构造函数进行构造,如果本类存在vtable那么将本类的vtable地址赋值给vptr。时,a指针通过构造函数进行初始化,此时a内部的vptr指针会指向A的虚函数表vtable。如果没有构造函数,编译器会生成默认的空构造函数。

2024-04-22 16:08:42 579

原创 C++设计模式:中介者模式(十五)

定义:用一个中介对象来封装(封装变化)一系列的对象交互。中介者使各个对象不需要显示的相互引用(编译时依赖 -> 运行时依赖),从而使其耦合松散(管理变化),而且可以独立地运改变它们之间的交互。在软件构建过程中,经常会出现多个对象相互关联交互的情况,对象之间常常会维持一种付啊的引用关系,如果遇到一些需求的更改,这种直接的引用关系将面临不断的变化。在这种情况下,我们可以使用一个“中介对象”来管理对象之间的关联关系,避免相互交互的对象之间的紧耦合引用关系,从而更好地抵御变化。

2024-04-22 13:26:43 331

原创 C++高级特性:malloc、free和new、delete的区别(十二)

malloc、free都是用于动态分配内存空间的操作,malloc是C语言中的库函数,new是C++中的操作符。delete需要对象类型的指针,它通过调用析构函数进行释放当对指针类型进行擦除或者强制转换后会导致出现异常。free传入void *类型的指针即可,但是free有个很重要的问题,它怎么知道需要释放多大的空间?new是在free store上分配内存的,free store的意思就是可以自由分配。new返回的是对象类型的指针,malloc返回的是void *之后进行类型转换。

2024-04-22 10:40:26 521

原创 C++高级特性:C/C++内存结构模型(十一)

代码段可制度数据段通常在程序加载时有操作系统加载到内存,一旦加载就不能被修改在函数调用时,函数的机器码也存储在代码段中,每个函数有其独特的代码段地址字符串常量等只读数据段中的数据是不可修改的,任何企图修改这些数据的尝试都会导致运行时错误作为一个专业的C++使用者来说,清楚的知道自己的代码变量存储的区域会有非常大的好处,补单能够写出高性能代码,而且有助于减少一些深层次的BUG。使用C++内存的一些注意事项内存泄漏:确保在动态分配内存后找个合适的时机释放掉,避免出现内存泄漏。

2024-04-21 17:48:24 1099 1

原创 C++设计模式:适配器模式(十四)

定义:将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的哪些类可以一起工作。在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象”放在新的环境中应用,但新环境要求的接口是这些现存对象所不满足的。如何应对这种“迁移的变化”?如何既能利用现有对象的良好视线同时又能满足心得应用环境所要求的接口?

2024-04-21 13:41:30 375

原创 C++高级特性:nullptr和NULL的区别(十)

可以看到nullptr被定义为nullptr_t类型同时nullptr_t的类型长度与void *长度相同>=201103L#endif而nullptr_t也可以定义一个其他指针的空指针对象并且与nullptr有相同的能力,而且被创建的对象是一个左值//报错,右值没有地址。

2024-04-19 11:07:50 419

原创 C++高级特性:四种类型转换(九)

C++标准规定,试图修改一个被声明为。

2024-04-18 21:14:58 782

原创 C++高级特性:可变长模板参数和折叠表达式(八)

&表示万能引用,需要注意的是如果不使用万能引用,传入参数的类型需要注意是左值还是右值,要与模板的参数类型匹配。可变长参数是C++类模板编程中非常重要的一个东西,也是C++11引入的新特性,通过使用…来表示参数长度不固定。可以通过sizeof…(args)获取传入参数的个数数量。C++11之后写这种模板函数的递归需要写一个空参函数和。参数,而在C++17之后可以折叠表达式展开。

2024-04-18 21:13:23 133

原创 C++设计模式:代理模式(十三)

增加一层”是软件系统重对许多复杂问题的一种常见解决方法。在面向对象系统中,直接使用某些对象会带来很多问题,作为间接层的proxy对象便是解决这一问题的常用手段。具体proxy设计模式的实现方法、实现粒度都相差很大,有些可能对单个对象做细粒度的控制,如copy-on-write技术,有些可能对组件模块提供抽象代理层,在架构层次对对象做proxy(例如aop)Proxy并不一定要求保持接口完整的一致性,只要能够实现间接控制,有时候损失一些透明性也是可以接受的。

2024-04-13 22:25:41 1025

原创 C++高级特性:万能引用、引用折叠与完美转发(七)

由于出现了万能引用,现在传入参数就会变得很复杂,一会传入左值一会传入右值,通过模版参数接手的时候,实际上编译器呢会进行引用折叠的一个操作。那现在的结果就跟我们的需求背道而驰了啊,希望func(std::move(s))调用右值引用的func_push。万能引用:无论传入什么值还是引用都能够接收,并且确定其一个准确的类型,通过引用折叠的方式。一个左值引用的func_push、一个右值引用的func_push函数,二者是重载的关系。完美转发:我按照小明给我的方式(拷贝or移动)使用,这就叫完美转发!

2024-04-13 15:30:41 814

原创 C++高级特性:柯里化过程与std::bind(六)

其实上面的链式编程或者函数式编程就是一个柯里化的过程,其实这种操作在lambda表达式也有体现的,lambda表达式中继续lambda表达式。通过分析可以看到add(1)应该返回一个类似函数的东西func,然后这个东西还可以继续func(2)…现在需要完成这样一个需求:有一个函数每次调用返回的结果不一样。可以给一个全局的变量(静态变量),每次调用对这个全局变量进行值的修改然后返回,这样每次返回都不一样。如果需要用类来完成,那么可以使用operator()仿函数来做,仿函数其实是一个特殊的函数。

2024-04-12 20:55:04 443

原创 C++设计模式:门面模式(十二)

接口隔离”模式:在组建构建过程中,某些接口之间直接的依赖常常会带来很多问题、甚至根本无法实现。采用添加一层间接(稳定)接口,来隔离本来相互紧密关联的接口是一种常见的解决方案。门面设计模式定义:为子系统中的一组接口提供一个一致(稳定)的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用(复用)。上述A方案的问题在于组件的客户和组件中各种复杂的子系统有了过多的耦合,随着外部客户程序和各子系统的烟花,这种过多的耦合面临很多变化的挑战。如何简化外部客户程序和系统间的交互接口?

2024-04-12 16:16:20 625

原创 C++高级特性:右值引用与转移语义(五)

所有权的转移取决于实现。移动语义并没有太多神奇的事情去做,std::move只是用来匹配到移动构造(移动赋值)所有权与移动语义密不可分,可以说移动语义的诞生就是为了区分这个到底是转移所有权还是进行拷贝复制。

2024-04-12 14:15:37 337

原创 C++高级特性:重新理解左值、右值、左值引用与右值引用详解(四)

另外还有引用初始化的问题,引用只能在定义的时候初始化(定义的时候必须指定一个类型)。定义完毕无法初始化和修改指向,虽然无法修改指向但是可以修改值。b = y:实际上是将y的右值给了b当右值,不是把y的左值给了b当右值。int&b = x;b = y;/* 输出*/左值引用不是引用不了一个临时变量值吗,那右值引用来引用临时变量(东厂管不了的西厂管)右值引用却无法引用一个存在地址的左值(有实际地址)// 报错int t = 10;int& a = t;// 报错。

2024-04-11 23:48:00 1106

原创 C++设计模式:享元模式(十一)

概述:享元模式和单例模式一样,都是为了解决程序的性能问题。面向对象很好地解决了"抽象"的问题,但是必不可免得要付出一定的代价。对于通常情况来讲,面向对象的成本大豆可以忽略不计。但是某些情况,面向对象所带来的成本必须谨慎处理。定义:运用共享技术有效地支持大量细粒度的对象。在软件系统中采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统中,而带来很高的运行时代价——主要指内存需求方面的代价。如何避免大量细粒度对象问题的同时,让外部客户程序仍然能够透明地使用面向对象的方式来进行操作?

2024-04-11 18:41:32 577

原创 C++高级特性:共享指针shared_ptr和弱指针weak_ptr(三)

一个函数返回一个unique_ptr的智能指针有一个很强的兼容性,可以用unique_ptr接受也可以用shared_ptr接受。很明显这里会发现university和teacher相互依赖,导致shared_ptr的计数引用无法降为0形成了死锁。unique_ptr可以转化为shared_ptr,shared_ptr无法转化为unique_ptr。解决方案:只需要将其中一个的shared_ptr弱化成weak_ptr指针即可。在释放对象时二者都不肯先一步析构,最后无法析构导致内存泄漏。

2024-04-11 15:12:53 165

原创 C++高级特性:独享智能指针unique_ptr(二)

C++11中通过引入智能指针的概念,使得C++程序员不需要手动释放内存。先准备一个Cat.h和一个Cat.cpp,如下。

2024-04-11 15:11:25 1053

原创 C++高级特性:Lambda表达式(一)

f1和f2是同一个函数都是用于求a + b的和其中函数f1和f2的类型可以具体指定通过std::function模板类来指定,也可以通过auto自动类型推导对于lambda表达式,不光可以函数类型自动推导,函数的传入参数、返回类型都可以自动推导…f3的lambda表达式相当于auto f3(auto a, auto b)这样一个函数f3(auto a, auto b)很好理解,可以当做一个函数模板来看,结果人家在函数模板的基础在返回类型继续auto…(C++14新特性)

2024-04-10 22:35:16 592

原创 C++设计模式:单例模式(十)

由于程序运行CPU会进行指令的重排序,如果执行的指令是132顺序,A线程执行完13之后并没有完成对象的初始化、而这时候转到B线程;不能重复创建、也必须保证这个对象在多线程使用过程中不会因为创建而产生数据安全问题,即多线程抢占的创建这一个对象。可以看到实例化不止一个单例对象,这一现象违反了单例的思想,因此需要在多线程抢占创建时进行互斥(mutex)对外暴露一个public方法获取该对象,如果在获取时发现该对象为空,那么进行实例化,否则直接返回。因此可以看到实例化只有一次,多次获取到的对象的地址属于同一个。

2024-04-10 18:55:40 890

原创 C++设计模式:构建器模式(九)

定义:将一个复杂对象的构建与其表示相分离,使得同样的构建过程(稳定)可以创建不同的表示(变化)在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构建而成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定如何应对这种变化?如何提供一种“封装机制”来隔离出“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”不随着需求改变而改变?

2024-04-10 17:02:14 589

原创 C++:Stmt预处理SQL与大文件存取(五)

这里主要通过ftsream来计算文件的大小,也可以通过其他手段,例如stat.h、lseek函数(Linux环境)MySQL中存取文件可以用blob来表示,表示使用二进制的方式存储。

2024-04-09 19:51:19 342

原创 C++设计模式:原型模式(八)

定义:使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象。在软件系统中,经常面临着“某些结构复杂的对象”的创建工作;由于需求的变化,这些对象经常面临着剧烈的变化,但是它们却拥有比较稳定一直的接口如何应对这种变化?如何向“客户程序(使用这些对象的程序)”隔离处“这些易变对象”,从而使得“依赖这些易变对象的客户程序”不随着需求改变而改变?个人理解:当一个类对象创建复杂、或者需要当前状态且当前状态这个对象又不允许被破坏的情况下,为了重复利用就可以考虑使用原型模式来clone一个对象。

2024-04-09 14:18:24 700

原创 C++设计模式:抽象工厂模式(七)

抽象工厂定义:提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定它们具体的类动机:在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时,由于需求的变化,往往存在更多系列对象的创建工作。如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制来避免客户程序和这种“多系列具体对象创建工作”的紧耦合?个人理解:在工厂方法的基础上套上了一层封装接口,封装的意义就是为了在工厂方法的基础上返回一套或者同类的相互依赖的一系列对象!

2024-04-09 10:45:22 560

原创 C++设计模式:工厂方法模式(六)

对象创建模式:通过对象创建模式绕开new,来避免对象(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定。它是接口抽象之后的第一步工作。PrototypeBuilder工厂模式定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟(目的:解耦,手段:虚函数)到子类。动机在软件系统中,经常面临着创建对象的工作;由于需求的变化,需要创建的对象的具体类型经常变化。如何应对这种变化?

2024-04-08 16:03:13 975

原创 C++:MySQL的事务概念与使用(四)

脏读是致命的操作,因为拿到的数据是无效数据;而不可重复度与幻读是一种现象,只是先后读取不一致的问题,但是数据是有效的(其他事物成功提交)!

2024-04-07 23:40:05 665 1

原创 C++:MySQL数据库的增删改(三)

C/C++操纵数据库的方式便捷性太差,虽然JDBC的也很烂,但是JDBC有开源的ORM框架(mybatis、jooq、hiberate、springdata…),不敢想象如果全裸使用C/C++写一些业务会有多痛苦,捂脸!

2024-04-07 19:23:50 398

原创 C++设计模式:桥模式(五)

桥模式定义:将抽象部分(业务功能)与实现部分(平台实现)分离,使他们可以独立地变化引入动机由于某些类型的固有的实现逻辑,使得它们具有两个变化的维度,乃至多个维度的变化如何应对这种“多维度的变化”?如何利用面向对象技术来使用类型可以轻松地沿着两个乃至多个方向变化,二部引入额外的复杂度?Bridge模式使用“对象间的组合关系”解耦了抽象和实现之间固有的绑定关系,使得抽象和实现可以沿着各自的维度来变化。所谓抽象和实现沿着各自维度的变化,即“子类化”它们。

2024-04-07 14:51:53 687

原创 C++:执行SQL和获取查询结果(二)

遍历和清理结果集api:mysql_fetch_row、mysql_fetch_lengths、mysql_free_result。获取结果集api:mysql_use_result、mysql_store_result。执行sql语句的api:mysql_real_query和mysql_query。

2024-04-06 23:54:00 519

原创 C++:连接MySQL数据库(一)

mysql_real_connect函数:用于与MySQL数据库建立连接。mysql_options函数:用于设置一些连接超时、断开重连等。

2024-04-06 18:13:10 631

原创 C++设计模式:装饰器模式(四)

装饰器模式定义:动态(组合)地给一个对象增加一些额外的职责。就增加功能而言,Decorator模式比生成子类(继承)更为灵活(消除重复代码 & 减少子类个数)。在某些情况下我们可能会“过度地使用继承来扩展对象的功能”,由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀。如何使“对象功能的扩展”能够根据需要来动态地实现?同时避免“扩展功能的增多”带来的子类膨胀问题?

2024-04-06 14:18:29 1108

原创 C++设计模式:观察者模式(三)

观察者模式定义:定义对象间的一种1对多(变化)的依赖关系,以便当一个对象(Subject)的状态发生比改变时,所有依赖于它的对象都得到通知并且自动更新再软件构建过程中,我们需要为某些对象建立一种“通知依赖关系“——一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知。如果这样的依赖关系过于紧密,僵尸软件不能很好地抵御变化。使用面向对象技术,可以将这种依赖关系弱化,并形成一种稳定的依赖关系。从而实现软件体系结构的松耦合。

2024-04-05 19:38:29 944

原创 C++设计模式:策略模式(二)

定义一系列算法,把它们一个个封装起来,并且使它们可互相替换(变化),该模式使得算法可独立于使用它的客户程序(稳定)而变化(扩展,子类化)在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都硬编码到对象中,将会使对象变得异常复杂;而且有时候支持不适用的算法也是一个性能负担(代码段过长)如何在运行时根据需要透明地更改对象的算法?将算法与对象本身解耦,从而避免上述问题?Strategy及其子类为组件提供了一系列的可重用的算法,从而可以使得类型在运行时。

2024-04-05 13:52:31 1184

原创 Makefile:make install的实现(十一)

这个脚本的意思是将可执行文件的执行指令写入到08_main_start启动脚本中,并且把输出结果重定向到08_main.log日志文件中,并且在后台运行(不占用bash),在输出一些提示。:将08_main_start启动脚本软连接到/usr/local/bin下,使得可以全局执行,下同。:生成可执行目标,这里的可执行目标比较简单,这也是第一个目标,也就是make默认执行的入口。:这是make clean的执行目标,主要就是清除上面生成的这些文件和软链接的环境变量。:否则就开始进行文件的一些操作和连接。

2024-04-05 11:43:51 658

原创 Makefile:条件判断、循环、自定义函数(十)

Makefile中提供了自定义函数,但并非是真正的函数。本质是将多行命令放在了外面,使用时将其包含进来调用格式:$(call 函数名)# 自定义函数并不是真正的函数,本质上是多行命令放在了外面,使用时将其包含进来a:=123b:=$(a)endefa:=456show:a:=789# 输出func789 123func789 123函数的传参问题,函数可以传参,但是没有返回值与C/C++的main参数一样,0号参数是本身,1号参数开始才是传入的参数。

2024-04-03 22:50:16 267

原创 Makefile:调用shell脚本和嵌套调用多项目编译(九)

【代码】Makefile:调用shell脚本和嵌套调用多项目编译(九)

2024-04-03 21:23:44 318

原创 C++设计模式:TemplateMethod模式(一)

定义一个操作中的算法的骨架结构(稳定),而将一些步骤延迟(变化)到子类中。Template Method使得子类可以不改变(复用)一个算法的骨架结构即可重定义(override重写)该算法的某些特定步骤在软件构建过程中,对于某一项任务,它常常有稳定的整体操作结构,但是各个子步骤却有很多改变的需求,或者由于固有的原因(比如框架与应用之间的关系)而无法和任务的整体结构同时实现如何在确定稳定操作结构的前提下,来罗应对各种各个子步骤的变化或者晚期实现需求?

2024-04-03 15:21:43 1319

原创 Makefile:通用部分头文件与条件判断(八)

首先举个例子看看为什么需要这个东西,例如在一个文件夹下有两个项目,两个项目都需要编写makefile编译,此时可以使用公共头文件。对比上面两个makefile,其主要的不同就是一个项目下是.cpp文件,一个是.c文件,而下面编译的代码几乎相同。:可以理解为引用,可以在makefile中写一个a=$(a)的指令就会报出自身引用自身的错误。:可以理解为赋值,这个值只与当前行之前的变量值有关,先把值拿出来赋值好,后面在修改与其无关。而=被认为是引用,因此只有最后才知道值,a一旦修改b引用a的值也会被修改。

2024-04-02 21:06:53 361

原创 C++多线程:RAII技术、recursive_mutex、timed_mutex(十二)

recursive_mutex递归的独占互斥量(可重入锁),允许同一个线程对同一个互斥量进行多次lock,效率上比mutex要差一些,重入的次数有限制,次数太多可能报异常。带超时功能的递归互斥量,std::recursive_mutex和std::timed_mutex的结合版本,也没什么新奇的东西。但这个关键区域(CRITICAL_SECTION)与互斥量(Mutex)存在一定的差异,关键区域是可以进行锁重入的,而Mutex并不支持。在使用时应该尽量的减少这个锁的使用,应该优先考虑程序的优化。

2024-04-02 15:50:16 386

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除