自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 c++的运算符重载的局限性

需要注意的是,这些函数只能被定义为成员函数,而不能被定义为全局函数或友元函数。除了上述函数,其他函数可以被定义为全局函数或友元函数。只有无法修改该对象的代码时,才建议重载为全局函数,但重载全局函数需要在运算对象的类内设置友元,所以语法上支持,但实际情况是个死局。1、重载运算符的目标是为了提高代码可读性、实用性,如果达不该效果建议定义为函数。2、重载运算符函数时,要符合情况情理,不要反人性,不要成为你炫技的工具。,也叫赋值函数,要进行深拷贝时就需要重载。,可以把对象伪装成函数使用。sizeof 长度运算符。

2024-09-11 19:20:00 390

原创 c++的运算符重载

2、由于cin、cout都在>>、<<运算的左边,如果想实现成员运算符函数,就需要在istream、ostream类中实现,而我们无法增加或修改istream、ostream类的代码,所以只能实现全局的 >>、<< 运算符函数。1、cin、cout是标准库中具有输入、输出功能的类对象,它的类名叫istream、ostream,当我们想给某种类对象增加输入、输出的功能时,就需要实现 >>、<<运算符函数对于该类对象的支持,也就是重载输入、输出运算符。

2024-09-11 19:18:13 771

原创 c++的运算符函数

如果运算对象是自定义类型,还可以把运算符函数实现该类型的内部,a+b的运算符函数格式为。C++中把运算符当作函数处理,在表达式中遇到运算符时,编译器会先寻找相关的运算符函数。,一般由左边的运算对象发起调用,右边的运算对象作为参数。,运算对象都做为参数传递给该函数。格式的函数,这种函数又被称为。例如a+b,会先寻找。

2024-09-11 19:13:49 365

原创 c++的单例模式

只能创建出一个对象的结构、联合、类叫单例模式。

2024-09-10 19:05:50 1135

原创 c++的静态成员

被static修饰过的成员变量叫静态成员变量。class Test// 静态成员public:被static修饰的成员函数叫静态成员函数。

2024-09-10 19:05:10 685

原创 c++的拷贝构造函数和赋值函数

是一种特殊构造函数,如果没有显式的实现,编译器就会自动生成。class 类名public:// 拷贝构造类名(const 类名& that)是一种特殊的成员函数,如果没有显式实现,编译器会自动生成。class 类名public:// 赋值函数const 类名& operator=(const 类名& that)

2024-09-10 19:04:32 1079

原创 c++的this指针与常函数

在成员函数的参数列表的末尾(小括号后面),用const修饰,这种成员就叫常函数。class 类名public:// 常函数返回值 函数名(参数列表) const在定义结构、联合、类对象时,使用const修饰,这种对象就叫常对象。const 类名 对象名;const 类名* 指针变量 = new 类名;

2024-09-08 23:51:04 1333

原创 c++的初始化列表与const成员

不能在构造函数中初始化const成员,因为执行构造函数时,类对象已经创建完成,只有类对象创建完成才能调用成员函数,构造函数虽然特殊但也是成员函数。在构造函数小括号后面,主要用于给const成员初始化的一种特殊语法,也可以给普通成员初始化(可以解决参数名与成员变量名同名的问题)。注意:如果有成员是类、结构、联合类型的,还可以在初始化列表中显式调用成员的构造函数,还可以调用父类的构造函数。使用const修饰的类、结构、联合的成员变量,在类对象创建完成前一定要初始化。// 可以使用,但只有C11标准才支持。

2024-09-08 23:50:21 489

原创 c++的构造函数与析构函数

如果类中有单参的构造函数,那么它的参数类型数据就能隐藏提升为类对象,如果不使用该功能,可以在单参构造函数的前面加 explicit 关键字,参数类型数据就不能再隐藏提升为类对象。注意:在使用new[] 创建n个对象时,无法保证给所有的类对象都单独提供参数,去调用有参构造,那么必然需要调用无参构造,此时如果没有显式实现无参构造,编译就会出错。在创建类对象时,一定会调用构造函数,如果类中没有显式实现构造函数,编译器会自动生成一个无参的什么都不做的构造函数。cout << "我是无参构造函数" << endl;

2024-09-08 23:49:48 1688

原创 c++的类和对象

把抽象结果(利用面向对象的思维模式,思考、观察出的结果),使用用C++的语法封装出一种类似结构的自定义数据类型(复合数据类型)。使用设计好的类(结构)这种数据类型,定义出的类变量在面向对象编程语言中被称为对象(结构变量),创建类对象的行为也被称为实例化对象。​int id;short age;public:cout << "请输入学生的学号、姓名、年龄、成绩:";// 学号:10010 姓名:hehe 年龄:18 成绩:100。

2024-09-06 17:58:05 844

原创 c++的面向过程与面向对象

2、在解决一个复杂庞大的问题时,把问题拆分成若干个小问题,每个小问题实现一个类去解决,最后把这若干个类通过继承进行汇总,达到解决问题的目的,这个方式可以降低问题的规模在难度,也方便团队分工、协作。,编译器在编译代码时根据语句的参数、环境不同,能翻译出具有不同功能的二进制指令,例如:调用重载的函数,cin、cout的自动类型识别,模板技术(后续讲解)。1、在解决一个问题之前,先考虑现有的类是否能解决部分问题,如果有则继承该类,在此基础上进行扩展,以缩短解决问题的时间(代码复用)。

2024-09-06 17:57:33 455

原创 c++的名字空间

在C语言中定义的全局变量、函数、结构、联合、枚举、枚举值、宏都在全局作用域下,所以当项目比较庞大时,非常容易造成命名冲突(以模块名作前缀、后缀),所以C++中选择把全局作用域进行拆分成子作用域进行管理,这些子作用域就是作名字空间。

2024-09-06 17:57:01 892

原创 c++操作符别名

C、C++语言中使用的运算符或符号,在个别地区的键盘上是没有的,为了让所有人都使用C++进行编程,所以就对个别的字符取了别名。&& 等价于 and。

2024-09-03 19:49:27 284

原创 c++类型转换

4、之所以设计这么复杂就是为了让程序员记不住,不使用强制类型转换,因为C++之父本贾尼·斯特劳斯特卢普认为好的代码设计就不应该使用强制类型转换,当需要强制类型转换时,他希望程序员去优化自己的代码不是使用强制类型转换。1、C语言中的强制类型转换语法在C++中还可以继续使用,但官方不建议这样,因为有安全隐患。2、void类型的指针不能再隐式转换成其它类型的指针。reinterpret_cast<目标类型>(数据)dynamic_cast<目标类型>(数据)static_cast<目标类型>(数据)

2024-09-03 19:48:53 376

原创 c++引用和指针

引用是一种取名机制,它可以给变量重新取一新的名字,所以引用也叫别名。

2024-09-03 19:48:15 538

原创 c++堆内存管理

6、在申请数组型的内存块时,使用new 类型[n],释放内存时使用delete[],不能与new/delete不能混用,因为new[]/delete[]会自动调用n次构造、析构函数,而new/delete只调用一次构造、析构函数。使用new[] 申请数组型的堆内存时(结构、联合、类对象),所申请内存块的前4个字节,记录着内存块的块数,所以使用delete []释放内存时可以准确调用n次析构函数。5、在C++中malloc系列函数为结构、联合、类对象申请、释放内存时,不会自动调用构造、析构函数。

2024-09-03 19:47:38 882

原创 c++的函数

C++标准委员会设计一种特殊函数,函数在声明时在返回值类型的前面增加 inline 关键字,当调用该函数时,编译器不会生成跳转指令,而是函数的二进制指令直接拷贝到调用位置,这样执行该函数时,直接执行二进制指令,不需要跳转,也不需要返回,所以执行速度比普通函数快,就像宏函数,但过多使用会造成冗余,代码段变大。2、g++在编译调用函数的语句时,会先尝试调用换名的函数,此时会发现没有该版本的函数声明,然后再尝试调用未换名的函数,这样编译器生成就是未换名的函数调用指令,就能成功调用C的库文件中的函数。

2024-09-02 19:38:50 997

原创 c++的结构、联合、枚举

2、在C++中结构、联合的内部,可以有成员函数,使用结构、联合对象加.或->调用,成员函数的内部可以直接使用成员变量,成员函数可以自动区别对象的成员变量。1、在C++中定义结构、联合对象时,struct、union关键字可以省略(也就不需要使用typedef进行类型重定义)。4、在C++中创建、销毁结构、联合对象时,会自动调用构造函数(以结构名命名)、析构函数(~结构名命名)。cout << "我是构造函数" << endl;cout << "我是析构函数" << endl;private 私有的成员。

2024-09-02 19:37:48 573

原创 c++的基本数据类型

在C语言中使用char类型的数组或char*指针指向的内存来存储字符串,使用string.h中的函数操作字符串,但在C++中使用string类型字符串变量,使用相关的运算符操作字符串。其它类型指针 可以自动转换成 void*,之所以保留是因为C标准库、操作系统、第三方库中有大量的函数的参数使用了void*作为参数,如果该功能不保留,这类函数就无法再正常调用。注意:string类型的底层,依然是使用char类型的指针、数组实现的,并不是一种全新的类型,而是对char字符串的封装。// 比较字符串,==!

2024-09-02 19:36:09 693

原创 c++的Hello World!

C++语言的标准库文件,文件名的末尾不带.h,iostream用于标准输入输出头文件,C语言的相关头文件还可以继续使用。为了统一命名风格,C++为C语言重定义了不带.h标准库头文件,例如:stdio.h重定义了cstdio。cout和cin可以自动识别数据类型,但输入输出复杂格式的数据时,没有printf和scanf好用。cout << 要输出的数据 << endl,多个数据用<<隔开。printf和scanf还可以继续使用,但需要包含相关的头文件。自定义的头文件,还可以继续以.h结尾。

2024-09-02 19:35:29 410

原创 操作系统信号量

功能:带倒计时的对信号减1操作,能减返回0成功,不能减超时返回-1失败,阻塞abs_timeout一段时间。功能:尝试对信号量减1操作,能减返回0成功,不能减返回-1失败,不会阻塞。O_CREAT 不存在则创建信号量,存在则获取。功能:信号量减1操作,如果信号量已经等于0,则阻塞。pshared:信号量的使用范围。功能:在内核创建一个信号量对象。功能:对信号量执行加1操作。value:信号量的初始值。功能:给信号量设置初始值。name:信号量的名字。mode:信号量的权限。功能:获取信号量的值。

2024-08-29 19:17:56 541

原创 操作系统条件变量

为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起,一般线程睡入条件变量,伴随着解锁动作,而线程从条件变量醒来时,伴随着加锁动作,如果加锁失败线程进入阻塞状态,而不是睡眠。注意:使用互斥锁配合条件变量实现的生产者与消费者模型,能够平衡生产与消费的时间不协调,并且可以最大限度的节约运行资源。// 从条件变量cond中叫醒一个线程,令其重新获得原先的互斥锁。// 使调用线程睡入条件变量cond,同时释放互斥锁mutex。1、线程等待"条件变量的条件成立"而休眠;// 从条件变量cond中唤醒所有线程。

2024-08-29 19:17:23 1048

原创 生产者与消费者模型

也叫数据仓库,是生产者线程与消费者线程之间的数据缓冲区,用于平衡二者之间的生产速度与消耗速度不均衡的问题,通过缓冲区隔离生产者和消费者,与二者直连相比,避免相互等待,提高运行效率。生产数据的线程,这类的线程负责从用户端、客户端接收数据,然后把数据Push到存储中介。负责消耗数据的线程,对生产者线程生产的数据进行(判断、筛选、使用、响应、存储)处理。解决方法:负责生产的线程通知负责消费的线程全速消费,然后进入休眠。解决方法:负责消费的线程通知负责生产的线程全速生产,然后进入休眠。

2024-08-29 19:16:51 870

原创 操作系统原子操作

所谓的原子操作就是不可被拆分的操作,对于多线程对全局变量进行操作时,就再也不用再线程锁了,和pthread_mutex_t保护作用是一样的,也是线程安全的,有些编译器在使用时需要加-march=i686编译参数。2、type只能是整数相关的类型,浮点型和自定义类型无法使用。功能:把value赋值给*ptr,并返回*ptr的旧值。功能:以上操作返回的是*ptr与value计算后的值。使用原子操作实现一个线程安全的无锁队列。1、该功能并不通用,有些编译器不支持。功能:以上操作返回的是*ptr的旧值。

2024-08-28 19:47:50 9295

原创 如休防止出现死锁

2、破坏占有且等待的条件,一次申请完成它所有需要的资源(把所有资源进行打包,用一把锁来代表,拿到这反锁就相当于拿到的所有资源),资源没有满足前不让它运行,一旦开始运行就一直归它所有, 缺点是系统资源会被浪费。3、破坏不可剥夺的条件,当已经占有了一些资源,请求新的资源而获取不到,然后就释放已经获取到的资源,缺点是实现起来比较复杂,释放已经获取到的资源可能会造成前一阶段的工作浪费。printf("没有构成死锁!printf("没有构成死锁!printf("没有构成死锁!方法1:阅读代码,分析各线程的加锁步骤。

2024-08-28 19:47:11 346

原创 什么是死锁

多个线程互相等待对方资源,在得到所需要的资源之前都不会释放自己的资源,然后造成循环等待的现象,称为死锁。

2024-08-28 19:46:27 457

原创 操作系统读写锁

使用读写锁的线程应根据后续的操作进行加锁,如果只对数据进行读取则只加读锁即可,只有对数据进行修改时才应该加写锁,与互斥锁的区别是,它能让只读的线程加上锁,使用原理与文件锁一样。功能:尝试加读锁,如果不能加则立即返回。功能:尝试加写锁,如果不能加则立即返回。功能:带倒计时加读锁,超时则立即返回。功能:带倒计时加写锁,超时则立即返回。读锁 写锁 NO。写锁 读锁 NO。写锁 写锁 NO。功能:加读锁,如果不能加则阻塞等待。功能:加写锁,如果不能加则阻塞等待。

2024-08-27 18:37:59 500

原创 操作系统互斥锁

功能:加锁,当互斥锁已经是锁定状态时,调用者会阻塞,直到互斥被解开,当前线程才会加锁成功并返回。2、线程1调用pthread_mutex_lock函数,立即返回,互斥量呈锁定状态;5、线程2被唤醒,从pthread_mutex_lock函数中返回,互斥量呈锁定状态。4、线程1调用pthread_mutex_unlock函数,互斥量呈非锁定状态;3、线程2调用pthread_mutex_lock函数,阻塞等待;功能:解锁,解锁后等待加锁的线程才能加锁成功。功能:初始化一互斥锁,会被初始化为非锁定状态。

2024-08-27 18:37:26 571

原创 操作系统线程同步

如进程、线程同步,可理解为进程或线程A和B一块配合,A执行到一定程度时要依靠B的某个结果,于是停下来,示意B运行;B依言执行,再将结果给A,A再继续操作。同步就是协同步调,按预定的先后次序进行运行。“同”字从字面上容易理解为一起动作,其实不是,“同”字应是指协同、协助、互相配合。在多线程编程里面,一些敏感数据不允许被多个线程同时访问,此时就使用同步访问技术,保证数据在任何时刻,最多有一个线程访问,以保证数据的完整性。注意:同一个进程内存的多个线程之间,除了栈内存是独立的,其他资源全部共享。

2024-08-27 18:36:54 423

原创 操作系统线程属性

多线程并不能提高运行速度,反而可能会降低,所以多线程不适合解决运算密集性问题,而是适合解决等待、阻塞的问题,如果使用进程去等待,会浪费大量资源,所以使用更轻量的线程去等待,节约资源。"进程级竞争" : "未知");// PTHREAD_SCOPE_PROCESS(Linux不支持) - 在进程范围内竞争资源。"轮转" : "未知");// PTHREAD_INHERIT_SCHED(缺省) - 调度属性自创建者线程继承。

2024-08-26 19:55:45 674

原创 操作系统取消线程

缺省情况下,线程在收到取消请求以后,并不会立即终止,而是仍继续运行,直到其达到某个取消点。成功返回0,并通过oldstate参数输出原可取消状态(若非NULL),失败返回错误码。PTHREAD_CANCEL_ENABLE - 接受取消请求(缺省)。被取消线程可以在任意时间取消,不是非得遇到取消点才能被取消。在取消点处,线程检查其自身是否已被取消了,并做出相应动作。被取消线程在接收到取消请求之后并不立即响应,功能:该函数只是向线程发出取消请求,并不等待线程终止。(若非NULL),失败返回错误码。

2024-08-26 19:55:04 526

原创 操作系统线程分离

注意:如果若干个子线程需要长时间执行,不知道什么时候能结束,为了避免它父线程陷入无尽的等待,可提前给子线程设置分离状态。同步方式(非分离状态):创建线程之后主线程调用pthread_join函数等待其终止,并释放线程资源。功能:使thread参数所标识的线程进入分离(DETACHED)状态。异步方式(分离状态):无需创建者等待,线程终止后自行释放资源。返回值:成功返回0,失败返回错误码。

2024-08-26 19:54:31 285

原创 操作系统终止线程

printf("子线程:%lu %d\n",pthread_self(),i);printf("我是主线程,我要结束了,倒计时:%d\n",3-i);主线程结束,并不会导致子线程跟着一起结束,它们之间没有必然联系。子线程在一定时间内会结束,侧使用pthread_join。当子线程的结束时间不确定,则使用pthread_exit。注意:这种情况会产生新的问题,子线程的资源没有办法回收。方法1:从线程入口函数中return,主线程除外。等待所有子线程结束,主线程再执行return 0;

2024-08-26 19:54:00 441

原创 获取线程ID、判断线程ID

注意:某些实现的pthread_t不是unsigned long int类型,可能是结构体类型,无法通过“==”判断其相等性。功能:若参数t1和t2所标识的线程ID相等,则返回非零,否则返回0。成功返回调用线程的ID,不会失败。

2024-08-26 19:53:28 141

原创 操作系统线程回收

3、线程入口函数所返回的指针指向text、data、bss内存段的数据,如果指向heap内存段,则还需保证在用过该内存之后释放之。1、线程过程函数将所需返回的内容放在一块内存中,返回该内存块的首地址,保证这块内存在函数返回,即线程结束,以后依然有效;2、若retval参数非NULL,则pthread_join函数将线程入口函数所返回的指针,拷贝到该参数所指向的内存中;retval:获得线程正常结束时的返回值,是输出型的参数,用于获取线程入口函数的返回值。返回值:成功返回0,失败返回错误码。

2024-08-23 22:11:55 106

原创 操作系统创建线程

thread - 线程ID,输出型参数。启动线程本质上就是调用一个函数,只不过是在一个独立的线程中调用的,函数返回即线程结束。返回值:成功返回0,失败返回错误码,但不会修改全局的错误变量,也就是无法使用perror获取错误原因。attr - 线程属性,NULL表示缺省属性,如果没有特殊需求,一般写NULL即可。1、restrict: C99引入的编译优化指示符,提高重复解引用同一个指针的效率。start_routine - 线程入口函数指针,参数和返回值的类型都是void*

2024-08-23 22:11:06 569

原创 POSIX线程库

POSIX线程(POSIX Threads,常被缩写为pthread)是POSIX的线程标准,定义了创建和操纵线程的一套API。​ 实现POSIX 线程标准的库常被称作pthread,一般用于Unix-likePOSIX 系统,如Linux、Solaris。但是Microsoft Windows上的实现也存在,例如直接使用Windows API实现的第三方库pthread-w32。

2024-08-23 22:10:35 201

原创 线程与进程的区别(多进程与多线程)

同一进程中的各个线程共享该进程所拥有的资源,线程间可以直接读写进程数据段来进行通信,但需要线程同步和互斥手段的辅助,以保证数据的一致性。进程是个资源单位,线程是个执行单位,并且线程是进程的一部分,线程需要进程安身立命,进程也需要线程当牛做马。进程采用虚拟空间+用户态/内核态机制,所以就导致进程与进程之间是互相独立的,各自的资源不可见。多进程之间资源是独立的,所以需要通信,多线程之间资源是共享的,所以需要同步和互斥。多进程之间资源是独立的,多线程之间资源是共享的。

2024-08-21 19:59:46 377

原创 操作系统线程介绍

线程是操作系统能内够进行运算、执行的最小单位,它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。总结:线程是进程的一部分,是进程内负责执行的单位,进程是由资源单位(内存资源、信号处理方案、文件表)+执行单位组成,默认情况下进程内只有一个线程,但可以有多个。

2024-08-21 19:58:50 593

原创 XSI机制的进程间通信

X/Open国际联盟有限公司是一个欧洲基金会,它的建立是为了向UNIX环境提供标准,XSI是X/Open System Interface的缩写,也就是X/Open设计的系统接口。X/Open的主要的目标是促进对UNIX系统、接口、网络和应用的开放式系统协议的制定。它还促进在不同的UNIX环境之间的应用程序的互操作性,以及支持对电气电子工程师协会对UNIX的可移植操作系统接口规范。

2024-08-21 19:58:09 780

空空如也

空空如也

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

TA关注的人

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