
C/C++基础
主要是C/C++基础知识,想起啥写啥
KingOfMyHeart
会好起来的.
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
C++17 之 scoped_lock 死锁避免神器
用于多个互斥锁的免死锁 RAII 封装器,是一种更加灵活和安全的互斥量管理方式。是一种独占互斥锁,它可以同时锁定多个互斥锁,并保证以原子方式获得所有互斥锁,从而有效避免死锁。它可以接受多个互斥锁作为参数,并在构造函数中自动锁定这些互斥锁。当对象出作用域时,它会析构并自动解锁所有已经锁定的互斥锁,确保互斥访问的安全性和正确性。原创 2023-08-12 23:20:20 · 826 阅读 · 0 评论 -
C++14 17共享超时互斥锁 shared_timed_mutex / 共享锁 shared_mutex
共享锁,也叫。比如,在多线程环境下,多个线程操作同一个文件,其中读文件的操作比写文件的操作更加频繁,那么在进行读操作时,不需要互斥,线程间可以共享这些数据,随意的读取。但是一旦有写操作,那么一定要进行互斥操作,否则读取到的数据可能存在不一致。原创 2023-08-12 21:29:30 · 1785 阅读 · 0 评论 -
C++11 之 递归锁 recursive_mutex
在一些业务场景下,线程在获取锁后还会多次获取该锁,且保证不出现死锁或者程序崩溃异常。简单地说,递归锁是一种在。原创 2023-08-12 17:39:28 · 1915 阅读 · 0 评论 -
C++11之超时锁timed_mutex
超时锁:用来记录线程加锁 解锁 等竞争锁的过程,多用于调试多线程时使用。原创 2023-08-12 17:09:33 · 646 阅读 · 0 评论 -
C++使用mutex保护临界区时总是某一个线程在多次执行后才轮到下一个线程
记录一个有意思的现象,原创 2023-08-12 16:43:26 · 317 阅读 · 0 评论 -
详解C++特性之noexcept (C++11 C++17 C++20)
上面说到,noexcept()可以判断目标类型的移动构造函数是否可能抛出异常,那么我们可以先判断有没有抛出异常的可能,如果有,那么使用传统的复制操作,那么执行移动构造。实际上,这并不是最优解,因为很多自定义类型的拷贝构造也是很简单的,几乎不会抛出异常,我们还可以利用noexcept运算符的能力,判断类型的拷贝构造是否会抛出异常。判断类型是一个普通类型还是复杂的类型,如果是普通类型,返回true,则表示不会抛出异常,否则将表示可能会抛出异常。函数,则程序直接退出,否则跳转到处理异常的。在C++11前,使用。原创 2023-07-23 21:07:50 · 2004 阅读 · 0 评论 -
C++11之线程局部存储 thread_local
我们知道,在Linux系统中,子线程是通过复制来产生的,由于进程是资源分配的最小单位,那么,进程中的线程除了有自身运行时需要的一些栈空间,寄存器等资源,其余资源都是和其他线程共享的,这就会引入一些资源竞争的问题,为应用程序执行带来不确定性。而线程存储指的是一种特殊的内存机制,用于将数据存储在当前线程的私有内存中,这样线程就有自己私有的数据存储空间,不会被其他线程所干扰。实际上,线程局部存储早就出现,由于是一种特殊的内存机制,所以需要操作系统层面的支持。原创 2023-07-23 15:30:55 · 455 阅读 · 0 评论 -
容器适配器复习
实际上,容器适配器在工作中使用的不是特别多,所以对这些东西的个别细节难免有些遗忘,今天这里回顾一下。什么是适配器适配器类底层组合了已经有的容器对象,对外开发一些接口,这些接口实际上是对容器接口的封装,或者直接调用容器对象的方法。容器适配器没有自己的数据结构,没有自己的迭代器,实现全部依赖于底层的组合的容器。比如,template <class T,class Container = deque<T>>class stack{public: void pop() {原创 2022-05-30 20:55:01 · 190 阅读 · 1 评论 -
C++STL之双端队列deque
一说到队列,大家多数人和我一样,第一反应是FIFO原则。那么双端队列就是一个方向(头或者尾)就可以进也可以出,听起来我们的双端队列是一种具有队列和栈的性质的数据结构。是一种线性的数据结构,相比list增加 [] 运算符重载。大概长这个样子:实际上,在内存中这不是他的真实模样,比这个要复杂的多。一、双端队列deque的基本使用:#include <iostream>#inc...原创 2019-06-07 11:42:20 · 2709 阅读 · 0 评论 -
再聊C++多重继承之菱形继承
菱形继承的问题和内存布局class Base{public: Base(int){ std::cout << "Base()" << std::endl; }; ~Base(){ std::cout << "~Base()" << std::endl; };protected: int n;};class A : public Base{public: A(int a):Base(a){ std::cout <<原创 2022-05-14 16:16:42 · 412 阅读 · 0 评论 -
C++中如何定义指向类成员的指针
简单示例class Test{public: Test(){ std::cout << "Test()" << std::endl; }; void show() { std::cout << "show()" << std::endl; } static void fun(){ std::cout << "fun()" << std::endl; } int a; static int b;原创 2022-05-08 21:28:53 · 759 阅读 · 0 评论 -
再聊C++抽象类
什么是抽象类含有纯虚函数的类就叫做抽象类。抽象类不能定义对象,但是可以定义指针和引用。class Occupation{public: Occupation(){ std::cout << "Occupation()" << std::endl; }; //纯虚函数 基类给派生类预留的统一的接口,派生类必须实现 virtual void work() = 0;};再派生类中,纯虚函数必须实现,否则派生类还是一个抽象类:class Student : pub原创 2022-05-08 21:04:51 · 886 阅读 · 0 评论 -
C++中何时静态绑定,何时识别RTTI类型进行动态绑定?
静态绑定:编译时期就确定调用的是哪个方法,如模板,函数重载等动态绑定:程序运行时才确定调用的是哪个方法,即多态。何时静态绑定,何时识别RTTI进行动态绑定无论是基类指针(引用)指向基类对象,还是派生类指针(引用)指向基类对象,还是基类指针(引用)指向派生类对象,只要该指针调用的方法是一个虚函数,那么将发生动态绑定两要素:指针或者引用调用了虚函数。class Occupation{public: Occupation(){}; void show() { std::cout <&原创 2022-05-08 17:22:56 · 391 阅读 · 0 评论 -
C++虚析构函数
为什么需要将基类析构函数设置为虚函数我们来观察下面这段代码的表现:class Occupation{public: Occupation(){ std::cout << "Occupation()" << std::endl; }; ~Occupation(){ std::cout << "~Occupation()" << std::endl; }; void show() { std::cout << "Occupation原创 2022-05-08 16:24:46 · 779 阅读 · 0 评论 -
C++中哪些函数可以被设置为虚函数
成为虚函数的前提/要求虚函数将来是要被存放在虚函数表中的,所以函数能被取地址l;而虚函数表是存放在对象的前四个字节(一般),所以函数的需要调用依赖对象,取出对象的虚函数表的地址。常见函数鉴别:构造函数:不可以,此时对象不存在(构造函数中调用的任何函数都是静态绑定)析构函数:可以静态成员方法:不可以,静态方法调用不依赖对象...原创 2022-04-17 20:40:55 · 941 阅读 · 0 评论 -
C++虚函数,虚函数表指针和虚函数表详解
class Occupation{public: Occupation(){}; virtual void show() { std::cout << "Occupation::show()" << std::endl; } virtual void show(int) { std::cout << "Occupation::show(int)" << std::endl; }private: int name_;};虚函数被virtua原创 2022-04-17 20:24:14 · 1138 阅读 · 0 评论 -
C++继承中,支持从下到上的转换
实例继承中支持的是从下到上的转换。比如有个基类叫职业类, class Occupation;class Occupation{public: Occupation(); virtual ~Occupation();};然后可以派生出学生类,老师类,程序员类等, 如class Student;class Student : public Occupation{public: Student(); ~Student();};我们可以将派生类对象赋值给一个基类对象,换言之,学生原创 2022-04-17 11:43:04 · 731 阅读 · 0 评论 -
如何前向声明名字空间中的类
namespace A{ class Foo;}原创 2022-03-27 21:18:08 · 586 阅读 · 0 评论 -
ubuntu20.04安装nvidia-container-toolkit
docker: Error response from daemon: could not select device driver “” with capabilities: [[gpu]].然后按照网上的博客进行以下操作distribution=$(. /etc/os-release;echo $ID$VERSION_ID)curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -curl -s -L原创 2022-03-19 19:26:27 · 9863 阅读 · 1 评论 -
C与C++中的符号隐藏
C语言中的符号隐藏:我们知道,在C语言中,在.c文件中定义一个全局的变量,如果要在其他.c文件中访问,我们需要使用到extern,声明这个变量是引用的其他源文件中的变量,编译器在进行符号整理后,会给该符号一个正确的地址。当我们希望仅仅在当前文件访问一个符号(无论是函数还是变量),不希望其他源文件访问,也就是隐藏符号,我们可以使用static进行修饰。由于被static修饰的符号是local类型的,编译器不连接local符号,只处理globall符号。// example.cstatic int a原创 2022-03-19 19:25:51 · 2722 阅读 · 0 评论 -
C++重载:const char *类型参数被匹配为bool类型参数的函数,导致行为异常
现象:实现了一个接口类,包含了类似以下的接口:class {public: void Set(const std::string&value); void Set(const int&value); void Set(const double&value); void Set(const bool&value);};当我在程序中调用该方法时,发现,最终匹配竟是bool类型的重载版本:Set("value");分析:分析一下过程:“value”原创 2022-03-19 19:25:17 · 1474 阅读 · 0 评论 -
新基础类型(C++11~C++20)
整数类型long longlong long该类型实际上我们很早就开始使用了,但是是直到C++11才加入标准中的;long一般表示一个32位的整型,long long一般表示64位的整型;long long是一个有符号的整型,对应无符号是unsigned long long;C++标准顶定义,long long至少是一个64位的整型,注意,这里是至少。定义是可以使用LL和ULL进行区分:long long a = 10000;long long b = 10ll;unsigned long原创 2021-10-31 14:53:11 · 870 阅读 · 0 评论 -
error adding symbols: DSO missing from command line
错误usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libpthread.so: error adding symbols: DSO missing from command linecollect2: error: ld returned 1 exit status原因有的博客写的是对pthread库的缺失,但是我在编译的时候都链接了。然后调整了pthread的链接顺序,然后就可以了。...原创 2021-10-18 19:35:40 · 745 阅读 · 0 评论 -
C++中vector的push_back()和emplace_back()区别
push_back()创建一个新元素,然后拷贝构造到容器的末尾。emplace_back()直接在容器尾部构造对象,直接调用构造函数进行构造,省去对象拷贝构造的过程。有案例的链接原创 2021-06-30 22:34:52 · 309 阅读 · 2 评论 -
c++中vector的clear(),swap()以及 shrink_to_fit()方法
clear()仅仅将容器中的元素释放(析构)掉,会导致size = 0,但是容器容量capacity不会变,即占用内存没有变化。int main(){ std::vector<int> vec; std::cout<<vec.size()<<std::endl; std::cout<<vec.capacity()<<std::endl; for(int i= 0;i < 10;++i) {原创 2021-06-30 20:43:03 · 1989 阅读 · 0 评论 -
c++面试题:实现一个简单的线程池
#include <memory>#include <functional>#include <thread>#include <iostream>#include <vector>class Thread{public: using ThreadFunction = std::function<void()>; Thread(ThreadFunction func,int id):func_(func)原创 2021-06-20 17:03:00 · 1635 阅读 · 0 评论 -
c++面试题:按照你对shared_ptr的理解,实现一个shared_ptr
#include <iostream>#include <unordered_map>#include <atomic>class Count{public: Count() =default; ~Count() = default; void Add(void *ptr) { ptr_map_[ptr] ++; } int Dec(void *ptr) { a原创 2021-06-20 17:01:43 · 419 阅读 · 0 评论 -
c++面试题:实现一个生产者消费者队列
#include <thread>#include <mutex>#include <condition_variable>#include <queue>#include <iostream>class Queue{public: void Put(int val) { std::unique_lock<std::mutex> lck(mtx_); //队列不为空,通知原创 2021-06-20 17:00:00 · 1194 阅读 · 1 评论 -
assert()为何在NDEBUG版本上不起作用
#ifdef NDEBUG#define assert(e) ((void)0)#else#define assert(e) \ ((void) ((e) ? ((void)0) : __assert (#e, __FILE__, __LINE__)))#endif原创 2021-06-16 13:02:34 · 286 阅读 · 0 评论 -
如何正确的比较俩个结构体(对象)相等?为何不能使用mmecmp()?
正确方法:#includeusing namespace std;struct A{char ch;int val;// 友元运算符重载函数friend booloperator==(const A &ob1, const A &ob2);// 成员运算符重载函数bool operator==(const A &rhs...原创 2018-09-14 22:10:50 · 2413 阅读 · 0 评论 -
c++11新增的容器---array、forwardlist、unorderedcontainers
array:实际上就是对数组进行了包装看一下array的定义:templatestruct array{ typedef std::size_t size_type; typedef T value_type; typedef value_type *pointer; typedefvalue_type* ite...原创 2018-08-07 15:30:09 · 141 阅读 · 0 评论 -
C++STL容器迭代器失效问题
本文拿std::vector来举例说明,什么是迭代器失效:拿两个代码片段来说明迭代器失效现象:int main(){ vector<int> vec; for(int i = 0;i < 20 ;++i){ vec.push_back(rand()%100); } //打印一下 for(const int v:vec){ std::cout<<v<<" "; } std::c原创 2021-05-04 21:11:36 · 404 阅读 · 0 评论 -
C++运算符重载中有些方法为什么需要定义为友元函数
C++提供运算符重载主要目的:希望对象之间的运算看起来可以和编译器内置类型一样丝滑;相当于是告知编译器,类对象之间运算应该如何去做处理。通过实现一个复数类,来阐述本文章的主题:class Complex{public: Complex(int r = 1,int i = 1):real_(r),image_(i){} ~Complex(){} void print(){ std::cout<<"real_= "<<real_<原创 2021-05-04 17:12:54 · 2596 阅读 · 2 评论 -
虚继承解决菱形继承等不友好设计的问题
假如没有虚继承对于菱形继承等多重继承中,对象继承时,会有大量的重复的数据的继承,浪费内存,影响性能。class A{public: A(){} ~A(){}protected: int a;};class B:public A{public: B(){} ~B(){}protected: int b;};class C:public A{public: C(){} ~C(){}protected: int c原创 2021-05-02 21:03:57 · 142 阅读 · 0 评论 -
C++虚基类以及可能引发的一些问题
什么是虚基类:当一个类被派生类用virtual继承时,这个基类就叫做虚基类c++中virtual有两个作用,一个是修饰虚函数,另外一个就是这里修饰继承方式下面例子中A就是一个虚基类:class A{public:protected: int ma;};//虚继承,此时A被称为虚基类class B:virtual public A{public:protected: int mb;};虚基类和抽象类有什么区别:抽象类指的是,类中存在纯虚函数,即函数名=0这样的函数原创 2021-05-02 20:21:28 · 1311 阅读 · 1 评论 -
模板特例化与偏特化
模板是C++中一个很重要的特性,写一份代码能用于多种数据类型(包括用户自定义类型)。例如,STL的sort()函数可以用于多种数据类型的排序,类stack可以用作多种数据类型的栈。但是,如果我们想对特定的数据类型执行不同的代码(而不是通用模板)呢?这种情况下就可以使用模板特例化(template specialization)。一、函数模板特例化当特例化一个函数模板时,必须为原模板中的每个模板参数都提供实参。使用关键字template后跟一个空尖括号<>,即template <>转载 2021-04-29 22:21:36 · 487 阅读 · 0 评论 -
c++11中shared_from_this的使用情景与案例
class C{public: C(int b=10):a(b){ cout<<"construct"<<endl; } ~C(){ cout<<"destruct"<<endl; } void show()const{ cout<<"a = "<<a<<endl; } C*object_ptr(){ return this; }private: int a;};使用场景:原创 2021-04-29 22:06:09 · 6608 阅读 · 1 评论 -
记录几个C++智能指针shared_ptr常用方法
#include <memory>#include <iostream>using namespace std;class Test{public: Test(int b=10):a(b){ cout<<"construct"<<endl; } ~Test(){ cout<<"destruct"<<endl; } void show()const{ cout<<"a = "<<a原创 2021-04-29 21:28:39 · 191 阅读 · 0 评论 -
C++常成员方法与静态成员方法
class C{public: C(int val){} ~C(){} C() = default; void show(){ std::cout<<"C *this"<<std::endl; } void show()const{ std::cout<<"const C *this"<<std::endl; } static void test(){原创 2021-04-27 21:46:31 · 165 阅读 · 0 评论 -
环境变量LD_LIBRARY_PATH的含义和使用
主要作用:主要用于指定查找动态库时除了默认路径(如 /lib和/usr/lib等)之外的其他路径。使用场景:比如我们自己工程中的会有很多.so文件,对工程进行部署时,正常情况下我们是不会把这些库install到系统文件夹(/lib等)下面,这不通用,可能会影响其他用户对机器的使用,而且需要root权限,并不是所有的开发都会有root权限的。但是我们工程要跑起来需要用到这些库的符号,默认情况下,是不会加载没放在/lib 或者 /usr/lib中库,要想去指定加载我们工程目录中的库,需要设置LD_LIB原创 2021-04-20 21:48:28 · 5617 阅读 · 0 评论