![](https://img-blog.csdnimg.cn/20201014180756925.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
C++
休息一下接着来
这个作者很懒,什么都没留下…
展开
-
C++ 锁管理:std::lock_guard 和 std::unique_lock 使用方法
适用于简单的自动化锁定和解锁场景,功能有限但性能开销小。:适用于需要更复杂控制的场景,例如手动解锁、重新加锁及与条件变量配合使用,提供了更多的灵活性,但性能开销较大。原创 2024-07-05 17:09:46 · 334 阅读 · 0 评论 -
使用sstream库处理字符串流
sstream提供了一系列类,用于字符串流操作。下面是如何使用这些类的一些示例。原创 2024-06-28 11:13:48 · 164 阅读 · 0 评论 -
C++ 左值和右值
C++中左值(lvalue)和右值(rvalue)是比较基础的概念,虽然平常几乎用不到,但C++11之后变得十分重要,它是理解 move/forward 等新语义的基础。左值和右值主要的区别之一是左值可以被修改,而右值不能。左值与右值这两个概念是从 C 中传承而来的。左值指既能够出现在等号左边,也能出现在等号右边的变量;右值则是只能出现在等号右边的变量。2. 左值引用和右值引用左值引用:引用一个对象;右值引用:就是必须绑定到右值的引用,C++11中右值引用可以实现“移动语义”,通过 && 获得右值引转载 2022-06-14 10:38:36 · 967 阅读 · 0 评论 -
C++ 拷贝控制(五):阻止拷贝
有些类应该阻止拷贝,比如iostream类阻止了拷贝,以避免多个对象写入或者读取相同的IO缓存。如果我们不定义拷贝控制成员,但是编译器会默认为我们定义这些操作,因此不能阻止类的拷贝。通常阻止拷贝主要有定义删除函数和private拷贝控制两种方法。我们可以通过将拷贝构造函数和赋值拷贝运算符定义为删除函数来阻止拷贝。删除函数是一种函数,虽然我们定义了它们,但是不能以任何方式使用它们。特别注意:由于析构函数是public的,用户可以定义NoCopy类型的对象。但是由于拷贝构造函数和拷贝赋值运算符是privat原创 2022-06-09 15:33:50 · 2137 阅读 · 2 评论 -
C++ 拷贝控制(四):使用=default
可以通过将拷贝控制成员定义为 =default 来显示地要求编译器生成合成版本。特别注意:在类内使用=default修饰成员的声明时,合成的函数将隐式地声明为内联的(就像任何其他类内声明的成员函数一样)。如果不希望合成的成员时内联函数,应该只对成员的类外定义使用=default,就像上面拷贝赋值运算符随做的那样。...原创 2022-06-08 18:54:20 · 362 阅读 · 0 评论 -
C++ 拷贝控制(三):析构函数
析构函数执行与构造函数相反的操作:构造函数初始化对象的非static数据成员,还可能做一些其他的工作。析构函数释放对象使用的资源,并销毁非static数据成员。在一个析构函数中,不存在类似构造函数中,初始化列表的东西。来控制成员如何销毁,析构部分是隐式的。成员销毁时发生什么完全依赖于成员的类型。销毁的成员需要调用自己的析构函数销毁。内置类型没有析构函数,销毁内置类型什么也不需要做。注意:隐式销毁一个内置指针类型的成员不会delete它所指的对象。与普通指针不同,智能指针是类类型的,具有析构函数。智能指针成原创 2022-06-08 16:47:11 · 266 阅读 · 0 评论 -
C++ 拷贝控制(二):拷贝赋值运算符
与类控制其对象如何初始化一样,类也可以控制对象如何赋值:1. 重载赋值运算符重载运算符本质上是一个函数,由operator关键字后接要定义的运算符的符号组成。赋值运算符是由一个名为"operator="的函数。类似于其他任何函数,运算符函数也有一个返回类型和参数列表。为了与内置类型的赋值保持一致,赋值运算符通常返回一个指向其左侧运算对象的引用。标准库通常要求保存在容器中的类型要具有赋值运算符,且其返回值是左侧运算对象的引用与处理拷贝构造函数一样,如果一个未定义自己的拷贝赋值运算符,编译器会为它生成一个原创 2022-06-07 17:28:51 · 372 阅读 · 0 评论 -
C++ 拷贝控制(一):拷贝构造函数
拷贝控制,当定义一个类时,我们显式或隐式地指定在此类型的对象拷贝、移动、赋值和销毁时做什么。通过一下五种特殊的成员函数来控制这些操作:拷贝构造函数、移动构造函数、拷贝赋值运算符、移动赋值运算符、析构函数。如果我们没有定义这些拷贝控制成员,编译器会自动定义确实操作。因此很多类,忽略了这些拷贝控制操作。但是,有些类依赖这些操作默认的定义会导致意想不到的灾难。.........原创 2022-06-07 15:53:19 · 149 阅读 · 0 评论 -
C++ 内存分配(静态内存、栈和堆)
内存分为三种:静态内存、栈内存和堆内存1. 静态内存静态内存用来保存局部static对象、类的static数据成员、以及定义在任何函数之外的变量。保存对象:局部static对象void func(){ static int a; // 局部static对象}类的static数据成员class Function(){public: static void func(); // 类中static函数private: static int i_func; /转载 2022-04-27 18:03:20 · 1160 阅读 · 1 评论 -
C++ 字符串的截取
按照字符串截取/** * @brief 按照指定的字符串截取字符串 * @param str 需要截取的字符串 * @param pattern 按照该字符串截取 * @return 截取好的字符串vector */std::vector<std::string> splitStr(std::string str, std::string pattern){ std::string::size_type pos; std::vector<std.原创 2022-04-20 17:12:50 · 10633 阅读 · 1 评论 -
C++ 字节流指针(字符数组)与string类型的转换
字符数组换成string// 定义一个字符数组char a[4] = "asd";// 将字符数组换成字符串string result = string(a, a + sizeof(a));String转换成字符数组// 定义一个字符串string a = "asd";// 将String转换成字符数组char *result = const_cast<char*>(a.c_str());int length = a.size();...原创 2022-04-20 16:42:46 · 2123 阅读 · 0 评论 -
大小端及转换(C++)
1. 基本概念大小端表示数据在存储器中存放的顺序。大端模式: 数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放;小端模式:数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分权值低,和我们的逻辑方法一致。假如在一段内存中存储如下数据uint8_t A = 0xA1;uint8_t原创 2022-03-03 17:40:36 · 13169 阅读 · 0 评论 -
C++ string转换int型
使用sscanf()函数#include <iostream>int main(){ std::string test = "1,2,3,4"; int a , b; sscanf(test.c_str(), "%d,%d", &a,&b); std::cout <<"a: " << a << std::endl; std::cout <<"b: " << b <.原创 2022-02-08 15:43:21 · 725 阅读 · 0 评论 -
C++ 再探智能指针(三):weak_ptr
基础概念阅读另一篇文章:C++ 智能指针 : https://blog.csdn.net/qq_28256407/article/details/119377508weak_ptr是一种不控制所指向对象生存周期的智能指针,它指向由一个shared_ptr管理的对象。将一个weak_ptr绑定到一个shared_ptr的对象不会改变其引用计数。当shared_ptr被销毁,即使有weak_ptr指向对象,对象还是会被释放。weak_ptr支持的操作weak_ptr<T> w /原创 2021-11-04 17:00:29 · 653 阅读 · 0 评论 -
C++ 再探智能指针(二):unique_ptr
基础概念阅读另一篇文章:C++ 智能指针 : https://blog.csdn.net/qq_28256407/article/details/119377508unique_ptr支持的操作p // 将p当做一个条件判断,若p指向一个对象则为true*p // 解引用p,获得指向它的对象、p->mem // 等价于 (*p).mem 访问成员p.get() // 返回p中保存的指针(指向对象的普通指针)。如果智能指针释放了其对象,返回的指针也会被释放swap(p原创 2021-11-03 21:49:19 · 263 阅读 · 0 评论 -
C++ 再探智能指针(一):shared_ptr
【基础参考】C++ 智能指针: https://blog.csdn.net/qq_28256407/article/details/119377508shared_ptr支持的操作p // 将p当做一个条件判断,若p指向一个对象则为true*p // 解引用p,获得指向它的对象、p->mem // 等价于 (*p).mem 访问成员p.get() // 返回p中保存的指针(指向对象的普通指针)。如果智能指针释放了其对象,返回的指针也会被释放swap(p, q) //原创 2021-11-02 23:38:02 · 281 阅读 · 0 评论 -
C++ std::cout 打印不出来uint8_t 和 int8_t
今天在测试程序时发现,发现一直打印不出某些数据,检查了好多遍,没有发现问题。经过多次测试,发现凡是uint8_t和int8_t的数据,都无法用std::cout打印出来。随后写个小程序测试了一下,发现确实如此。查过资料才明白,其中的原因。不得不说是个好坑。。。#include<iostream>int main(){ uint8_t a = 10; int8_t b = 5; std::cout << "uint8_t a: " << a &原创 2021-10-27 23:30:42 · 6397 阅读 · 3 评论 -
C++ std::vector删除元素的几种方式及区别
容器vector在删除过程中,常用的函数。函数作用pop_back()删除 vector 容器中最后一个元素,该容器的大小(size)会减 1,但容量(capacity)不会发生改变。erase(iter)删除 vector 容器中iter迭代器指定位置处的元素,并返回指向被删除元素下一个位置元素的迭代器。该容器的大小(size)会减 1,但容量(capacity)不会发生改变。erase(iter1,iter2)删除 vector 容器中位于迭代器 [iter1,i原创 2021-10-24 23:19:30 · 31412 阅读 · 0 评论 -
C++ std::vector: vector中元素的存储方式 size、capacity、reserve、resize的使用
1. vector的对象的存储方式为了支持随机访问,vector将元素连续存储–每个元素紧挨着前一个元素存储。容器中元素是连续存储的,且容器的大小是可变的。在容器中增加元素时。vector根据存储元素的大小,在内存上申请一个空间,用于存储数据,空间的大小通常会大于所存储元素的实际大小,并且预留出一部分预留的空间,以便再次增加数据时,可以不用重新开辟空间。当容器再次增加新的元素后,首先判断预留的空间是否够用,如果够用直接在预留空间中存储。如果预留的空间不够,需要在内存中开辟一整块新的更大的空间,并将ve原创 2021-10-24 10:54:45 · 2628 阅读 · 0 评论 -
C++类: 类中的静态成员
类的静态成员与类本身直接相关,而不是类的各个对象保持关联1. 声明静态成员在成员声明之前,加上static关键字,使其与类的成员关联在一起。静态成员可以是public或者private的。惊天数据成员的类型可以使用常量、引用、指针、类类型等。#include <iostream>struct test{public: static int a; // 定义静态成员 static char b; // 定义静态成员public: static int m原创 2021-09-15 17:44:28 · 508 阅读 · 0 评论 -
C++类: 聚合类
1. 聚合类的基本概念聚合类使得用户可以直接访问其成员,并且具有特殊的初始化语法形式。当一个类满足如下条件时,我们说他是聚合的:所有成员都是public的。没有定义任何构造函数。没有任何类内初始值。没有基类,也没有virtual函数如:struct test{ int a; string b;};2. 聚合类赋初值的基本方法struct test{ int a; string b;};test x = {1, "hello world"};原创 2021-09-15 12:20:38 · 940 阅读 · 0 评论 -
C++类: 构造函数隐式转换及explicit关键字
1. 构造函数的隐式转换C++中, 一个参数的构造函数(或者除了第一个参数外其余参数都有默认值的多参构造函数), 承担了两个角色。构造;默认且隐含的类型转换操作符。#include <iostream>struct test{public: test(bool ii) {};};int main(){ test x = 1; // 隐式转换构造,拷贝初始化 test y(2); // 直接赋值构造}2.抑制构造函数的隐式原创 2021-09-15 11:02:45 · 364 阅读 · 0 评论 -
C++ 类:构造函数(2)
1. 构造函数初始值列表初始化与构造函数内赋值class test{public: test() { a = 10; // 构造函数内赋值(实际上在调用函数时,已经对a进行了初始化为0,此处是再次进行赋值) }public: int a;};class test{public: test() : a(10) {} // 利用构造函数列表进行初始化public: int a;};注意:虽然上述两种法效果相同:当构原创 2021-09-14 16:53:34 · 91 阅读 · 0 评论 -
C++ 类:访问控制与封装
1. 访问说明符在c++中,使用访问说明符加强类的封装性。public:定义在public说明符之后的成员在整个程序内被访问,public定义类的接口。private:定义在private说明符之后的成员可以被类的成员函数访问,但是不是被使用该类的代码访问,private部分封装了(隐藏了)类的实现细节。注意:一个类可以包含任意个访问说明符,对某个说明符出现的次数也没有限制。每个访问符说明了接下来成员访问的级别,其有效范围直到出现下一个访问说明符或者到达类的结尾处为止。2.clsss和stru原创 2021-09-12 12:13:58 · 105 阅读 · 0 评论 -
C++ 类:构造函数(1)
1. 构造函数的基本概念每个类都分别定义了他的对象被初始化的方式。类通过一个或几个特殊的成员函数来控制其对象的初始化过程,这些函数叫做构造函数。构造函数任务是初始化类对象的数据成员,无论何时只要类的对象被创建,就会执行构造函数。构造函数的名字和类的名字相同构造函数没有返回类型构造类型可以有多个,满足函数重载的规则2.合成的默认构造函数如果在类中没有定义任何构造函数,编译器会隐式的创建一个特殊的构造函数,来控制默认初始化的过程,这个函数叫做默认构造函数。初始化类的数据成员时:如果存在类内原创 2021-09-09 16:22:35 · 217 阅读 · 1 评论 -
C++函数: 函数指针
函数指针指向的是函数而非对象。和其他指针类型一样,函数指针指向某种特定的类型。函数的类型由它的返回类型和形参共同决定,与函数名无关。// 比较两个string对象长度bool lengthCompare(const string &, const string &);// pf指向一个函数,函数的参数是两个const string的引用,返回值是bool型bool (*p)(const string &, const string &); // 未初始化注意:原创 2021-09-08 22:27:04 · 122 阅读 · 0 评论 -
C++函数: 函数的返回值为引用或指针
1. 函数的返回值为引用如果函数的返回值为引用,则不需要创建无名临时对象,避免构造函数和析构函数的调用,从空间和时间上提高了程序执行的效率。例子:#include <iostream>#include <string>using namespace std;string& Test(string &temp_str) // 定义函数的返回值为引用类型{ return temp_str;}int main(){ string test("H原创 2021-09-08 18:03:00 · 3582 阅读 · 0 评论 -
C++工程调试的帮助:预处理功能 assert 和 NDEBUG
程序包含用于调试部分的代码,这部分代码只在开发程序时使用。当应用程序发布时,屏蔽掉调试代码。这种方法用到两项预处理功能:assert 和 NDEBUG。1. assert预处理宏assert是一种预处理宏,其实是一个预处理变量,其行为类似于内联函数。表达式assert(expr); // 首先对expr求值,如果表达式为假(0),assert输出信息,并终止程序执行// 如果表达式为真(非0),assert啥也不做注意:assert宏定义在头文件中,宏定义的名字由预处理器处理,而不是编原创 2021-09-08 18:00:40 · 927 阅读 · 0 评论 -
C++函数: 含有可变参数的函数
为了编写能处理不同数量实参的函数,C++11提供了几种方法:如果所有的实参类型相同,可以使用initializer_list的标准库类型如果实参类型不同,则需要使用可变参数模板(暂时不进行说明)省略符形参,仅仅用于C++和C通用的类型1. initializer_list 形参如果函数实参数量未知,类型相同,可以使用initializer_list的形参。 initializer_list是标准库的类型,定义位于头文件<initializer_list>中。提供的操作如下ini原创 2021-09-07 23:45:02 · 237 阅读 · 0 评论 -
C++函数: 程序的参数传递——带参数的main函数
int main(int argc, char *argv[]) { ... }int main(int argc, char **argv) { ... }// 上面两个式子完全的等效第二个形参argv是一个数组,它的元素是指向C风格字符串的指针;第一个形参表示数组中字符串的数量。当实参传递给main函数之后,argv的第一个元素指向程序的名字或者空字符串,接下来的元素依次传递命令行提供的实参。最后一个指针之后的元素保证为0;当使用argv中的实参时,一定要记住可选的实参从argv原创 2021-09-07 22:23:48 · 868 阅读 · 0 评论 -
C++ 智能指针shared_ptr按照自己定义的函数析构
实现功能:继承智能指针的类,利用智能指针开辟空间。在智能指针析构释放内存时,按照自己定义的方式释放。例子:#include <iostream>#include <memory>using namespace std;template<typename T>class MyClass : public shared_ptr<T>{public: explicit MyClass() : shared_ptr<T>(static_c原创 2021-09-04 09:05:18 · 951 阅读 · 0 评论 -
C++ 函数: 数组形参
1. 数组有两个特殊的性质:不允许数组的拷贝和赋值:不能将数组的内容拷贝给其他数组作为其初始值,也不能用数组为其他数组赋值。(一些编译器支持数组的赋值,这就是所谓的编译器扩展,最好避免使用非标准特性)int a[] = {0 ,1 ,2}; // 含有三个整数的数组int a2[] = a; //【错误】 不允许使用一个数组初始化另一个数组a2 = a; // 【错误】不允许把一个数组的值,直接赋给另一个数使用数组时,通常会将其转化成指针。通过以上两个性质可以看出,数组无法拷贝,原创 2021-08-31 22:27:52 · 2793 阅读 · 0 评论 -
C++中的显示转换
命名的强制类型转换:形式:cast-name<type>(expression);type是强制转换的类型,expression是强制转换的值。如果type是引用类型,则结果是左值。case-name是C++四种转换类型static_cast、dynamic_cast、const_cast和reinterpret_cast的一种。static_cast可以被用于强制隐形转换(例如,non-const对象转换为const对象,int转型为double,等等)作用于对象,它还可以用于原创 2021-08-23 23:11:06 · 350 阅读 · 0 评论 -
sizeof运算符
sizeof运算符返回一条表达式或一个类型名字所占的字节数。sizeof运算符满足右结合律,其所得的值是一个size_t类型。该运算符的运算对象有两种形式:sizeof (type) // 获取该类型所占的字节数sizeof exper // 获取表达式所占的字节数如下:sizeof *p // 返回p所指向空间的大小,sizeof和*的优先级相同,满足右结合律(表达式从右往左计算)。等价于 sizeof(*p)sizeof p // 返回指针所占空间的大小size原创 2021-08-22 18:19:20 · 371 阅读 · 0 评论 -
C++ 条件运算符 ? :
条件运算符(? :)将简单的(if-else)逻辑嵌套入单个表达式当中。cond ? expr1 : expr2 // 条件运算符的格式 其中 cond为判断的表达式,expr1和expr2为两个类型相同或者可能为某个公共类型的表达式。当cond为真是,对expr1求值,并返回该值;否则对expr2求值,并返回该值。例如:string finalgrade= grade < 60 ? "fail" : "pass"; // 如果grade < 60 返回pass 否则返回 pas原创 2021-08-22 13:29:49 · 585 阅读 · 0 评论 -
递增运算符和递减运算符(i++与++i的区别)
递增运算符(++) 和递减运算符(–)为对象的加1和减1操作提供了一种简单的书写形式。递增和递减运算有两种形式:前置版本和后置版本。前置版本(++i)前置版本首先将运算对象加1(或减1),然后将改变的对象作为求值的结果返回。后置版本(i++)后置对象也将运算对象加1(或减1),然后将对象改变之前的那个值得副本得结果返回。int i = 0, j = 0;std::cout << ++i << std::endl; // 前置版本,i的值为1,输出结果为2s原创 2021-08-15 18:52:29 · 495 阅读 · 0 评论 -
C++11 迭代器(iteration)
在C++中,迭代器(iteration)提供了一种更通用的机制来访问string对象的字符或者vector容器的元素。所有的标准库容器,都可以使用迭代器,但是只有少数几种才同时支持下标运算符。和指针不一样的是,获取迭代器不是使用取地址符,有迭代器的类型同时拥有返回迭代器的成员。如:这些类型都拥有begin和end成员。begin: 负责返回指向第一个元素(或第一个字符的迭代器)。end: 负责返回容器(或者string)“尾元素的下一个位置”的迭代器。(尾后迭代器)1. 迭代器的运算符*ite原创 2021-08-04 12:50:50 · 1389 阅读 · 0 评论 -
C++11 智能指针
智能指针是存储动态分配对象指针的类,用于生命周期的控制。当指针离开其作用域时,自动销毁动态分配的空间,防止内存泄漏。在C++编程中,应该尽量使用智能指针,在很大程度上可以避免内存泄漏。C++11中共有三个智能指针:shared_ptr, weak_ptr, unique_ptr使用智能指针需要包含头文件**#include**shared_ptrstd::shared_ptr采用引用计数,每一个shared_ptr的拷贝都指向相同的内容,当最后一个shared_ptr析构的时候,内存被释放。使原创 2021-08-04 10:00:37 · 133 阅读 · 1 评论 -
C++ std::vector
标准库类型vector表示对象集合,其中所有的对象的类型都相同。vector常常被称为容器(container)。使用vector时,需要引入对应的头文件。vector本质上是一个类模板。#include <vector> // 包含对应的头文件using std::vector1. vector的定义和初始化vector<T> v1; // v1 是一个空vector,它潜在的元素是T类型,执行默认初始化vector<T> V2(V1); //原创 2021-07-31 00:34:19 · 763 阅读 · 0 评论 -
C++ std::string类型
string和vector是c++两种重要的标准库类型。前者是可变长度字符串,后者表示可变长度的集合。使用类型string必须包含string头文件。同样作标准库的一部分,string定义在命名空间std中。#include <string> // 引入string的头文件using std::string;1. string的定义和初始化string s1; // 定义字符串s1,默认初始化为s1是一个空的字符串。string s2(s1); // s2是s1的副本原创 2021-07-29 23:24:28 · 986 阅读 · 1 评论