c++
文章平均质量分 81
c++相关问题
Dutkig
奔跑吧, 用绝望追不上的速度。
展开
-
C++(32)——多线程编程(互斥、同步、CAS原子操作)
线程线程是进程内部的一条执行序列或执行路径,一个进程可以包含多条线程。从资源分配的角度来看,进程是操作系统进行资源分配的基本单位。从资源调度的角度来看,线程是资源调度的最小单位,是程序执行的最小单位一个进程可以并发执行多个线程,每个线程会执行不同的任务。对应在现实生活中,进程是组长,线程是小组成员。语言级别的多线程的优势:可以跨平台运行其原理就是:语言层面上的thread可以通过编译器的编译的宏信息识别操作系统,系统底层使用仍然是使用底层API如下:windows:createThre原创 2022-03-19 22:24:10 · 880 阅读 · 2 评论 -
C++(31)——C++11常用知识点整理
前言C++11在如今的公司开发过程中,C++11的代码形式和一些优秀的开源代码中,都会使用到C++11的一些特性,使得代码更加简洁,逻辑更加清楚。C++11的新标准很多,但是对于开发者来说,我们不一定会都使用到,本文主要总结一下之前的编码过程中高频出现的的内容。关键字与语法方面auto:可以根据右值,推导出右值的类型,然后左边变量的类型也就已知了nullptr:给指针专用(能够和整数进行区别)以前的NULL是一种宏定义,即#difine NULL 0,我们在代码中其实是无法区分整数和地址,有了n原创 2022-03-19 16:23:36 · 1088 阅读 · 0 评论 -
C++(30)——lambda表达式原理及应用
lambdalambda这个词起源于数学上的λ,在C++中利用lambda表达式,可以方便的定义和创建匿名函数。lambda可以看做函数对象的升级版。改进了函数对象以下的缺点:使用在泛型算法中的参数传递的过程中比较性质/自定义操作优先级队列智能指针lambda表达式语法[捕获外部变量](形参列表)->返回值{操作代码};如果lambda不需要返回值,那么返回值可以省略。也就是这样:[捕获外部变量](形参列表){操作代码};捕获外部变量的方式:[]:表示不捕获任何外部变量原创 2022-03-19 16:05:15 · 1254 阅读 · 0 评论 -
C++(29)——bind绑定器和function函数对象
绑定器和函数对象函数对象我们之前以及提到了,函数对象就是类方法中有operator()运算符重载的。在使用时和函数很类似。绑定器在C++ STL库中有两个绑定器绑定器 + 二元函数对象 = 一元函数对象bind1st: operator()的第一个形参变量绑定成一个确定的值。bind2nd:operator()的第二个形参变量绑定成一个确定的值。但是其实在复杂的应用场景下,这两个绑定器并不能满足应用的需求,于是在C++11中从Boost库中引入了bind绑定器和function函数对象机制原创 2022-03-19 15:13:55 · 1407 阅读 · 0 评论 -
C++(28)——从自定义String和vector理解移动语义和完美转发
自定义vector和Sring的结合使用代码如下:class CMyString{public: CMyString(const char* str = nullptr) { cout << "CMyString(const char*)" << endl; if (str != nullptr) { mptr = new char[strlen(str) + 1]; strcpy(mptr, str); } else { mpt原创 2022-03-17 15:02:25 · 279 阅读 · 0 评论 -
C++(27)——从自定义String类型理解右值引用
前言我们是用之前的自定义String类,再一次对右值引用进行深入了解,尽管我们之前的博客已经谈到这个问题,先来回顾一下MyString:class CMyString{public: CMyString(const char* str = nullptr) { cout << "CMyString(const char*)" << endl; if (str != nullptr) { _pstr = new char[strlen(str) + 1];原创 2022-03-17 13:50:51 · 350 阅读 · 0 评论 -
C++(26)——对象被优化以后才是最高效的C++编程
对象应用优化我们都知道,C语言和C++在程序执行中,都是通过调用一系列的函数来实现的。并且,很多时候,编译器会帮助我们做一系列的事情,比如(在编译类的成员方法的时候,编译器默认添加 this 指针,以此来确定是哪一个对象调用了该成员方法)。得益于编译器或者说系统帮助我们做的一系列事情,我们可以更加方便地使用C++。但是凡事有利必有弊,因为系统有时候会自己调用一系列的函数,从另一个角度来说,也一定程度上降低了效率。而我们想要提高C++的执行效率,就需要了解程序(主要是对象)使用过程中都调用了哪些方法。先原创 2022-03-17 13:14:16 · 1072 阅读 · 0 评论 -
C++(25)——STL
STL内容一览c++ STL (standard template libaray)标准模板库一:标准容器1、顺序容器vector(向量容器)deque(双端链表容器)list(链表容器)2、容器适配器stackqueuepriority_queue(基于大根堆实现的优先级队列)3、关联容器(重点)无序关联容器 链式哈希表 增删查O(1)unordered_set(无序单重集合)unordered_multiset(无序多重集合)unordered_map(无序单重原创 2022-03-16 16:12:51 · 1192 阅读 · 0 评论 -
C++(24)——语言级别提供的四种类型强转的方式
前言不同于C语言的类型转换的不安全性,无检查机制,比如没有关系的类型间的转换。C++提供了更多的类型转换方式。语言级别提供的四种类型强转的方式const_cast :去掉(指针或引用)常量属性的类型转换static_cast:提供编译器认为安全的类型转换reinterpret_cast:类似于C风格的强制类型转换dynamic_case:主要用在继承结构中,可以支持RTTI类型识别的上下转换使用示例1、const_cast,使用时注意保持类型的一致,经常用在去常性的地方注意:<原创 2022-03-15 20:03:40 · 545 阅读 · 0 评论 -
C++(23)——理解多重继承(菱形继承、半圆形继承)、虚基类和虚继承
多重继承概念: 一个派生类如果只继承一个基类,称作单继承,那么如果继承了多个基类,就称作多继承。比如:class C:public A,public B{};多重继承的优点:多重继承可以做更多的代码复用!派生类通过多重继承,可以得到多个基类的数据和方法,更大程度的实现了代码复用。多重继承有优点,那就也会存在缺陷:首先我们通过菱形继承了解一下多重继承的缺陷:菱形继承菱形继承是多继承的一种:如下图所示:图中的继承关系会产生什么样的问题呢?我们通过如下的代码示例理解一下:class原创 2022-03-15 19:23:03 · 6765 阅读 · 0 评论 -
C++(22)——容器的迭代器失效问题
前言我们在之前的学习中已经实现过list和vector的迭代器,那么在面试中经常会有面试官问到有关于迭代器的失效问题,那么为什么迭代器会失效呢?原因随着VS版本的迭代,g++版本的迭代,C++标准库容器以及迭代器的源码都有比较大的修改,但是迭代器失效的问题本质归纳起来就两点:不同容器的迭代器是不能进行比较的容器的元素进行insert、erase操作后,当前位置到末尾的迭代器 就全部失效了注意:当容器调用erase或insert方法后,当前位置到容器末尾元素的所有迭代器全部失效,或者扩容操作,原创 2022-03-14 16:40:02 · 841 阅读 · 3 评论 -
C++(21)——vector及实现自定义vector以及allocator和iterator
简介作用:vector是一个能够存放任意类型的动态数组,能够增加和压缩数据。vector是表示可以改变大小的数组的序列容器。与数组一样,vector对元素使用连续的存储位置,这意味也可以使用指向其元素的常规指针上的偏移量来访问它们的元素,并且与在数组中一样高效。但是与数组不同,它们的大小可以动态变化,容器会自动处理它们的存储。在内部,vector 使用个动态分配的数组来存储它们的元素。这个数组可能需要重新分配,以便在插入新元素时增大大小,这意味着分配一个新数组并将所有元素移动到其中。就处理时间而言原创 2022-03-14 14:51:03 · 3311 阅读 · 0 评论 -
C++(20)——弱引用智能指针weak_ptr
前言在正式介绍weak_ptr之前,我们先来回忆一下shard_ptr的一些知识,我们直到shared_ptr是采用引用计数的智能指针,多个shared_ptr实例可以指向同一个对象,并维护了一个共享的引用计数器。深入weak_ptr也是一个引用计数型智能指针,但是它不增加对象的引用计数,即弱引用。与之相对,shared_ptr是强引用,只要有一个指向对象的shared_ptr存在,该对象就不会析构,直到指向对象的最后一个shared_ptr析构或reset()时才会被销毁。利用weak_ptr,我原创 2022-03-13 16:09:11 · 1176 阅读 · 1 评论 -
C++(19)——智能指针shared_ptr
shared_ptr的概念shared_ptr实现共享式拥有(shared ownership)概念。多个智能指针可以指向相同对象,该对象和其相关资源会在“最后一个引用(reference)被销毁”时候释放。基本原理智能指针是(几乎总是)模板类,shared_ptr 同样是模板类,所以在创建 shared_ptr 时需要指定其指向的类型。shared_ptr 负责在不使用实例时释放由它管理的对象,同时它可以自由的共享它指向的对象。shared_ptr 使用经典的 “引用计数” 的方法来管理对象资源。原创 2022-03-11 14:26:12 · 889 阅读 · 0 评论 -
C++(18)——智能指针unique_ptr
简介unique_ptr 是 C++ 11 提供的用于防止内存泄漏的智能指针中的一种实现,独享被管理对象指针所有权的智能指针。unique_ptr对象包装一个原始指针,并负责其生命周期。当该对象被销毁时,会在其析构函数中删除关联的原始指针。unique_ptr对象始终是关联的原始指针的唯一所有者,我们无法复制unique_ptr对象,它智能移动。首先我们利用STL提供的unique_ptr管理对象时,不能完成下面框出的操作:上述操作受限与否的原理是什么?和之前一样,我们模仿源码的逻辑,看看uniq原创 2022-03-10 13:53:17 · 1033 阅读 · 1 评论 -
C++(17)——智能指针初步及弃用auto_ptr的原因
RAII使用局部对象来管理资源的技术RAII的原理RAII的四个步骤裸指针存在的问题:delete后的指针变量就变成了一个失效指针(也叫作悬空指针)。对于下面的代码:void Destroy(Object *op){ delete op; delete[] op;}Object *op = new Object(10);Object *arop = new Object[10];Destroy(op);Destroy(arop);因此:智能指针智能指针的引入原创 2022-03-09 14:06:36 · 2774 阅读 · 0 评论 -
C++(16)—— 抽象类
前言上一讲我们提到了纯虚函数,接下来由此展开抽象类的学习概念含有纯虚函数的基类是不能用来定义对象的。纯虚函数没有实现部分,不能产生对象,所以含有纯虚函数的类是抽象类。抽象类是一种特殊的类,它是为了抽象和设计的目的而存在的,它处于继承层次结构的较上层。抽象类是不能定义对象的,在实际中为了强调一个类是抽象类,可将该类的构造函数说明为保护的访问控制权限。作用将有关的组织在一个继承层次中,由它来为它们提供一个公有的根,相关的子类是从这个根派生出来的。注意 :子类如果不重写父类中的纯虚函数,原创 2022-03-08 16:37:45 · 1236 阅读 · 0 评论 -
C++(15)——多态与虚函数
多态性多态性(polymorphism)是考虑不同层次的类中,以及在同一个类中,同名的成员函数之间的关系问题。函数的重载,运算符的重载,属于编译时的多态性(早期绑定:编译期就确定了调用关系)。以虚函数为基础的运行时的多态性(晚期绑定:程序在运行过程中才能确定调用关系 是面向对象程序设计的标志性特征,体现了类推和比喻的思想方法。...原创 2022-03-07 16:25:18 · 824 阅读 · 0 评论 -
C++(14)——继承
继承性继承机制(inheritance)是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能。这样产生的类,称为派生类,继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认识过程。概念通过继承的机制可对类分层,提供类/派生类的关系,C++通过类派生的机制支持继承,被继承的类称为基类或超类,新产生的类为派生类。基类和派生类的集合叫做继承的层次结构。公有私有问题struct在声明一个类型时,默认情况下其属性值为公有,将其看做一个数据集合cl原创 2022-03-06 14:34:22 · 448 阅读 · 0 评论 -
C++(13)——STl之List的实现
STLSTL是C++的标准模板库,是一个具有工业强度,高效的C++程序库。STL一个最为重要的特点就是数据结构和算法的分离,你可以使用其中的一些函数操作几乎热河的数据集合,包含链表,容器和数组。STL的另一个特性就是它不是面向对象的,STL主要依赖模板而不是封装,继承和虚函数(多态性)STL中包含的六大组件容器(container):包含list、vector、deques,以模板类的方法提供,为了访问容器中的数据,可以使用由容器类输出的迭代器。迭代器(iterator):提供为了访问容器原创 2022-03-04 17:35:04 · 477 阅读 · 0 评论 -
C++(12)——命名空间,模板函数,模板类
模板函数相当于“图纸”template<class Type> //type是一个类型const Type & Max(const Type &a, const Type &b){ return a>b?a : b;} int main(){ int a = Max(12, 34); char ch = Max('a','b');原创 2022-02-16 18:28:36 · 850 阅读 · 0 评论 -
C++(11)——静态成员
回顾:我们都知道C中的静态在修饰局部变量或函数和全局变量时是不太一样的。局部变量可见性在其所在函数内部,并将其存储到.data区,在函数运行时只初始化一次,其生存期也会被延长,因此可以以引用方式返回。如果将函数或全局变量定义为静态,其生存期不会改变,仍然分别存放在代码区和.data区,但其只在定义它的文件中可见,同一个工程的其他文件不可见。静态数据成员在C++中静态数据成员有如下特点:在构造函数和拷贝构造函数中不能对静态数据成员进行列表方式构建,也就是不能在参数列表中对其进行初始化(在这两个原创 2022-02-13 20:47:27 · 750 阅读 · 0 评论 -
C++(10)——友元
友元采用类的机制后实现了数据的隐藏与封装,类的数据成员一般定义为私有成员,成员函数一般定义为公有的,依此提供类与外界间的通信接口。但是,有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁地访问类的数据成员,这时可以将这些函数定义为该类的友元函数。友元包括外部函数友元成员函数友元类友元。友元的作用是提高了程序的运行效率(即减少了类型检查和安全性检查等都需要时间开销),但它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。友元的3个特点:友元关系不能被继承,即若类B是原创 2022-02-13 20:47:15 · 304 阅读 · 0 评论 -
C++(9)——引用计数实现写时拷贝(包含String类的实现)
在之前的学习中,我们谈到了字符串的深拷贝与浅拷贝,在浅拷贝中,由于多个对象共用同一块内存空间,导致同一块空间被释放多次而出现问题,那能否保证:当多个对象共享一块空间时,该空间最终只释放一次呢?这就是我们接下来要谈的问题:引用计数对于我们之前所写的String类,在拷贝构造时,深拷贝方式使得使得各个对象都指向了独立的堆区空间,造成了内存和资源的浪费。因此,我们引入引用计数:其原理如下:原理:,当多个对象共享一块资源时,要保证该资源只释放一次, 只需记录有多少个对象在使用该资源即可,每减少(增加).原创 2022-02-13 20:47:04 · 491 阅读 · 0 评论 -
C++(8)——移动语义
在现有的 C++ 机制中,我们可以定义拷贝构造函数和赋值函数。要实现转移语义,需要定义转移构造函数,还可以定义转移赋值操作符。对于右值的拷贝和赋值会调用转移构造函数和转移赋值操作符。移动语义:将内存的所有权从一个对象转移到另外一个对象,高效的移动用来替换效率低下的复制,对象的移动语义需要实现移动构造函数(move constructor)和移动赋值运算符(move assignment operator)。...原创 2022-02-13 20:46:48 · 1110 阅读 · 0 评论 -
C++(7)——浅拷贝与深拷贝
浅拷贝浅拷贝主要是指:位拷贝,拷贝构造函数,赋值重载浅拷贝会把指针变量的地址复制,多个对象共用同一块资源,同一块资源释放多次,崩溃或者内存泄漏。具体请看下面的例子:#define SEQ_INIT_SIZE 10#define SEQ_INC_SIZE 2class SeqList{ int *data; int maxsize; int cursize;public: SeqList() :data(NULL),maxsize(SEQ_INIT_SIZE), cursize(0)原创 2022-02-13 20:46:35 · 262 阅读 · 0 评论 -
C++(6)——左值,左值引用,右值,纯右值,右值引用
左值(lvalue)左值的定义表示的是可以获取地址的表达式,它能出现在赋值语句的左边,对该表达式进行赋值。但是修饰符const的出现使得可以声明如下的标识符,它可以取得地址,但是没办法对其进行赋值:C11中,将所有可以寻址的值都称为左值-(可以把左值当成有名字的对象,所有的变量,包括常变量,都是左值。)int a = 10;a就是左值,因为可以寻址(&a),10就是右值(字面常量),也是纯右值,因为不可以&10;const int b = 20;b就是左值,因为可以寻址(&am原创 2022-01-19 15:06:06 · 748 阅读 · 0 评论 -
C++(5)——拷贝构造函数,组合、运算符重载
拷贝构造函数同一个类的对象在内存中有完全相同的结构,如果作为一个整体进行复制或者拷贝是完全可行的。这个拷贝过程只需要拷贝数据成员,而函数成员(只有一分拷贝),在建立对象时可用同一类的另一个对象来初始化该对象的存储空间,这时所用的构造函数称为拷贝构造函数。class Object:{ int value;public: Object(){} //缺省构造函数 Object(int x = 0):value(x){} //普通构造函数 ~Object(){} //缺省析构函数原创 2022-01-18 22:55:19 · 803 阅读 · 0 评论 -
C++(4)——引用的本质,const和指针的关系,const和引用的关系
const和指针的关系接下来我们将通过几段代码梳理const和指针的关系int a = 10;int* p1 = &a;int const * p2 = &a;const int *p2 = &a;int * const p3 = &a;const int * const p4 = &a;由于上述代码中未对变量a做常性约束,因此,之后的代码均可以编译通过。再来看看下面的代码:int a = 10;const int* s = &原创 2022-01-13 17:02:01 · 374 阅读 · 0 评论 -
C++(3)——this指针,常对象常方法的调用关系,thiscall,内联,using指示符
C++对程序的编译过程①识别类中的属性成员(记录在案)②识别类中的方法(只识别方法的声明(原型))形参名可以不给,形参类型必须给;③改写:(添加this指针)包括该函数形参列表、以及各个函数体内属于类中属性的成员前都加上this指针。//改写前:void CGoods::RegisterGoods(char name[], int amount, float price)//改写后:void CGoods::RegisterGoods( CGoods * const this,char nam原创 2022-01-10 14:21:50 · 436 阅读 · 0 评论 -
C++(2)——构造与析构函数,new与malloc,free与delete,引用(深入),拷贝构造函数
构造函数数据成员多为私有的,要对它们进行初始化,必须用一个公有函数来进行。同时这个函数应该在且仅在定义对象时自动执行一次。称为构造函数(constructor)构造函数不由用户调动,而是由系统(编译器)自动调动构造函数的特征如下:函数名与类名相同构造函数无函数返回类型说明,不是void(实际上构造函数有返回值,返回的就是构造函数所创建的对象)在程序运行时,当新的对象被建立,该对象所属的类的构造函数自动被调用,在该对象生存期中也只调用这一次。构造函数可以重载。严格地讲,说明中可以原创 2020-10-26 17:08:15 · 1639 阅读 · 0 评论 -
C++(1)——与C的区别,类和对象
C和C++的区别:标准输入输出//c语言 C++#include<stdio.h> #include<iostream> using namespace std;int mian() int main() { { int a; int a; scanf("%d",&a); char原创 2020-10-24 19:59:58 · 411 阅读 · 0 评论