c++
文章平均质量分 53
我是纠结伦
这个作者很懒,什么都没留下…
展开
-
算法-----二叉树
开篇:先在开头总结一下,二叉树解题的思维模式分两类:1、是否可以通过遍历一遍二叉树得到答案?如果可以,用一个 traverse 函数配合外部变量来实现,这叫「遍历」的思维模式。2、是否可以定义一个递归函数,通过子问题(子树)的答案推导出原问题的答案?如果可以,写出这个递归函数的定义,并充分利用这个函数的返回值,这叫「分解问题」的思维模式。无论使用哪种思维模式,你都需要思考:如果单独抽出一个二叉树节点,它需要做什么事情?需要在什么时候(前/中/后序位置)做?其他的节点不用你操心,递归函数会原创 2022-05-15 15:08:25 · 337 阅读 · 0 评论 -
C++容器源码分析-----Vector
基本数据结构:基本上,STL ⾥⾯所有的容器的源码都包含⾄少三个部分: 迭代器,遍历容器的元素,控制容器空间的边界和元素的移动; 构造函数,满⾜容器的多种初始化; 属性的获取,⽐如 begin(),end()等;迭代器:template <class T, class Alloc = alloc>class vector {public: // 定义 vector ⾃身的嵌套型别 typedef T value_type; typedef value原创 2022-05-12 11:08:49 · 1119 阅读 · 0 评论 -
C++11新特性-----tuple和pair
简介:在 C++ 中本已有⼀个 pair 模板可以定义⼆元组,C++11 更进⼀步地提供了边⻓参数的 tuple 模板:typedef std::tuple< int , double, string > tuple_1 t1;typedef std::tuple< char, short , const char * > tuple_2 t2 ('X', 2, "Hola!");t1 = t2 ; // 隐式类型转换 tuple是一个固定大小的不同类型值的集..原创 2022-05-11 10:01:12 · 494 阅读 · 0 评论 -
C++11新特性-----static_assert和assert
assert:原型定义:#include <assert.h>void assert( int expression );作用:计算表达式 expression ,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。例子: int a=1; int b=2; cout<<"next function is assert!"<<endl; assert((a<b ? 0:1));原创 2022-05-11 09:34:25 · 687 阅读 · 0 评论 -
C++11新特性-----final和override
C++ 借由虚函数实现运⾏时多态,但 C++ 的虚函数⼜很多脆弱的地⽅: ⽆法禁⽌⼦类重写它。可能到某⼀层级时,我们不希望⼦类继续来重写当前虚函数了。 容易不⼩⼼隐藏⽗类的虚函数。⽐如在重写时,不⼩⼼声明了⼀个签名不⼀致但有同样名称的新函数C++11 提供了 final 来禁⽌虚函数被重写/禁⽌类被继承, override 来显示地重写虚函数。 这样编译器给我们不⼩⼼的⾏为提供更多有⽤的错误和警告。final:C++11的关键字final有两个用途。第一,它阻止了从类继承;第二,阻止.原创 2022-05-10 09:35:04 · 324 阅读 · 0 评论 -
C++11新特性-----构造函数委托
在 C# 和 Java 中,⼀个构造函数可以调⽤另⼀个来实现代码复⽤,但 C++⼀直不允许这样做。 现在可以了,这使得构造函数可以在同⼀个类中⼀个构造函数调⽤另⼀个构造函数,从⽽达到简化代码的⽬的:class myBase { int number; string name; myBase( int i, string& s ) : number(i), name(s){}public: myBase( ) : myBase( 0, "invalid" ){} myBase(原创 2022-05-10 09:14:48 · 218 阅读 · 0 评论 -
C++11新特性-----类型推导(auto、decltype、强弱类型语言)
C++ 提供了 auto 和 decltype 来静态推导类型,在我们知道类型没有问题但⼜不想完整地写出类型的时候, 便可以使⽤静态类型推导。auto:for(vector<int>::const_iterator it = v.begin(); it != v.end(); ++it);// 可以改写为for(auto it = v.begin(); it != v.end(); ++it);虽然写起来和动态语⾔(如JavaScript的 var )很像,但C++仍然是强原创 2022-05-10 09:07:54 · 294 阅读 · 0 评论 -
Vector底层代码原理实现
定义初始结构:vector定义了三个指针start(表示目前使用空间的头)、finish(表示目前使用空间的尾)、end_of_storage(表示目前可用空间的尾)。template <class T>class vector{public: ~vector() { delete _start; _start = _finish = _end_of_storage = nullptr; }private: T*原创 2022-05-09 22:57:25 · 310 阅读 · 0 评论 -
C++-----generate() 和 generate_n()(有例子)
generate:作用 以指定动作运算结果填充特定范围内的元素内容 template <class ForwardIterator, class Generator>void generate (ForwardIterator first, ForwardIterator last, Generator gen);generate_n:作用 以指定动作的运算结果填充n个元素内容 template <class OutputIterator, cl原创 2022-05-09 12:00:29 · 204 阅读 · 0 评论 -
C++11新特性-----变长的对象初始化列表
C++11 提供了 initializer_list 来接受变⻓的对象初始化列表:class A{public: A(std::initializer_list<int> list);};A a = {1, 2, 3};注意初始化列表特性只是现有语法增强,并不是提供了动态的可变参数。该列表只能静态地构造c++11标准中,initializer_list对于标准库的编写影响非常大,说一个简单的例子,在c++11之前,max函数的源程序是这样的:template <原创 2022-05-09 11:51:14 · 219 阅读 · 0 评论 -
C++11新特性-----泛化的常量表达式constexpr
int N = 5;int arr[N];编译器会报错: error: variable length array declaration not allowed at file scope int arr[N]; ,但 N 就是5,不过编译器不知道这⼀点,于是我们需要声明为 const int N = 5 才可以。但C++11的泛化常数给出了解决⽅案constexpr int N = 5; // N 变成了⼀个只读的值int arr[N]; // OKconstexpr 告诉编译器这.原创 2022-05-09 11:44:24 · 967 阅读 · 1 评论 -
C++11新特性-----lambada表达式(函数对象、闭包)
作用:Lambda 表达式实际上就是提供了⼀个类似匿名函数的特性,⽽匿名函数则是在需要⼀个函数,但是⼜不想费⼒去命名⼀个函数的情况下去使⽤的。利⽤ lambda 表达式可以编写内嵌的匿名函数,⽤以替换独⽴函数或者函数对象,并且使代码更可读。这里简单介绍一下函数对象:一个函数对象,即一个重载了括号操作符“()”的对象。当用该对象调用此操作符时,其表现形式如同普通函数调用一般,因此取名叫函数对象。举个最简单的例子:class myprint{ public: voi原创 2022-05-09 11:35:38 · 374 阅读 · 0 评论 -
C++11新特性-----nullptr详解(((void *) 0)的含义和void)
nullptr 出现的⽬的是为了替代 NULL。 在某种意义上来说,传统 C++ 会把 NULL、 0 视为同⼀种东⻄,这取决于编译器如何定义 NULL,有些编译器会将NULL定义为 ((void*)0),有些则会直接将其定义为 0。这里讲一下关于((void*)0):在c语言中,0是一个特殊的值,它可以表示:整型数值0,空字符,逻辑假(false)。表示的东西多了,有时候不好判断。尤其是空字符和数字0之间。为了明确的指出,0是空字符的含义,用用到了: ((void *) 0) 这原创 2022-05-09 10:12:14 · 879 阅读 · 0 评论 -
从原理上讲解i++和++i的区别
先说结论:++i (前置加加)先⾃增 1再返回,i++ (后置加加)先返回 i 再⾃增1。++i 实现:int& int::operator++ (){ *this +=1; return *this; }i++ 实现:const int int::operator(int){ int oldValue = *this; ++(*this); return oldValue; }...原创 2022-05-09 09:59:08 · 82 阅读 · 0 评论 -
STL 中迭代器的作用,有指针为何还要迭代器
迭代器 Iterator(迭代器)模式⼜称 Cursor(游标)模式,⽤于提供⼀种⽅法顺序访问⼀个聚合对象中各个元素, ⽽⼜不需暴露该对象的内部表示。或者这样说可能更容易理解:Iterator模式是运⽤于聚合对象的⼀种模式,通过运⽤该模式,使得我们可以在不知道对象内部表示的情况下,按照⼀定顺序(由iterator提供的⽅法)访问聚合对象中的各个元素。由于Iterator模式的以上特性:与聚合对象耦合,在⼀定程度上限制了它的⼴泛运⽤,⼀般仅⽤于底层聚合⽀持类,如STL的list、vector、stack原创 2022-05-07 14:01:29 · 542 阅读 · 0 评论 -
C++中的set、unordered_set、map、unordered_map详解以及如何选择
set:set就是关键字的简单集合。当只是想知道一个值是否存在时,set是最有用的。一、set的模板参数介绍template < class T, // 表示set里面存放的数据类型 class Compare = less<T>, // 仿函数,可以指定让set按照什么方式进行比较数据 class Alloc = allocator<T> // 空间配原创 2022-05-07 13:50:49 · 2562 阅读 · 0 评论 -
C++序列容器实现-----vector(扩容及回收、swap方法)
vector 是动态空间,随着元素的加⼊,它的内部机制会⾃⾏扩充空间以容纳新元素。vector 维护的是⼀个连续的线性空间,⽽且普通指针就可以满⾜要求作为 vector 的迭代(RandomAccessIterator)。 vector 的数据结构中其实就是三个迭代器构成的,⼀个指向⽬前使⽤空间头的 iterator,⼀个指向⽬前使⽤空间尾的iterator,⼀个指向⽬前可⽤空间尾的iterator。当有新的元素插⼊时,如果⽬前容量够⽤则直接插⼊,如果容量不够,则容量扩充⾄两倍,如果两倍容量不⾜,原创 2022-05-07 09:56:02 · 1524 阅读 · 0 评论 -
哪些函数不能是虚函数?
构造函数,构造函数初始化对象,派⽣类必须知道基类函数⼲了什么,才能进⾏构造;当有虚函数时,每⼀个类有⼀个虚表,每⼀个对象有⼀个虚表指针,虚表指针在构造函数中初始化; 内联函数,内联函数表示在编译阶段进⾏函数体的替换操作,⽽虚函数意味着在运⾏期间进⾏类型确定,所以内联函数不能是虚函数; 静态函数,静态函数不属于对象属于类,静态成员函数没有this指针,因此静态函数设置为虚函数没有任何意义。 友元函数,友元函数不属于类的成员函数,不能被继承。对于没有继承特性的函数没有虚函数的说法。 普通函数,普原创 2022-05-06 10:55:49 · 206 阅读 · 0 评论 -
C++构造函数和析构函数的具体执行算法
构造函数:在派⽣类构造函数中,所有的虚基类及上⼀层基类的构造函数调⽤; 对象的 vptr 被初始化; 如果有成员初始化列表,将在构造函数体内扩展开来,这必须在 vptr 被设定之后才做; 执⾏程序员所提供的代码;而当被扩展的类的构造函数:记录在成员初始化列表中的数据成员初始化操作会被放在构造函数的函数体内,并与成员的声明顺序为顺序; 如果⼀个成员并没有出现在成员初始化列表中,但它有⼀个默认构造函数,那么默认构造函数必须被调⽤; 如果 class 有虚表,那么它必须被设定初值;原创 2022-05-06 10:52:57 · 665 阅读 · 0 评论 -
C++默认构造函数
定义:默认构造函数(default constructor)就是在没有显式提供初始化式时调用的构造函数。它由不带参数的构造函数,或者为所有的形参提供默认实参的构造函数定义。如果定义某个类的变量(对象)时没有提供初始化式就会使用默认构造函数。合成的默认构造函数如果我们的类没有显示地定义构造函数,那么编译器就会为我们隐式地定义一个默认构造函数。这个由编译器创建的构造函数又称为合成的默认构造函数(synthesized default constructor)合成的默认构造函数只适合非常简单的类,原创 2022-05-06 10:31:27 · 4492 阅读 · 0 评论 -
C++中初始化列表,何时需要成员初始化列表?
初始化列表定义:与其他函数不同,构造函数除了有名字,参数列表和函数体之外,还可以有初始化列表,初始化列表以冒号开头,后跟一系列以逗号分隔的初始化字段。class foo{public: foo(string s, int i) :name(s), id(i) {}; // 初始化列表private: string name; int id;};示例:class Test1{public: Test1() // 无参构造函数 { cout << "Con原创 2022-05-06 09:58:32 · 364 阅读 · 0 评论 -
动态链接和静态链接区别
你是否知道引用的那些头文件中的函数是怎么被执行的呢?这就要牵扯到链接库了!!! 库有两种,一种是静态链接库,一种是动态链接库,不管是哪一种库,要使用它们,都要在程序中包含相应的include头文件。我们先来回顾一下程序编译的过程。如下图:静态链接:静态连接库就是把 (lib) ⽂件中⽤到的函数代码直接链接进⽬标程序,程序运⾏的时候不再需要其它的库⽂件;静态链接的优缺点: 静态链接的缺点很明显,一是浪费空间,因为每个可执行程序中对所有需要的目...原创 2022-05-05 11:15:08 · 1842 阅读 · 0 评论 -
define、const、typedef、inline 使⽤⽅法?
1、const 与 #define 的区别 const 定义的常量是变量带类型,⽽ #define 定义的只是个常数不带类型; define 只在预处理阶段起作⽤,简单的⽂本替换,⽽ const 在编译、链接过程中起作⽤; define 只是简单的字符串替换没有类型检查。⽽const是有数据类型的,是要进⾏判断的,可以避免⼀些低级错误; define 预处理后,占⽤代码段空间,const 占⽤数据段空间; const 不能重定义,⽽ define 可以通过 #undef 取消某个符号的定原创 2022-05-05 10:49:20 · 155 阅读 · 0 评论 -
深拷贝和浅拷贝的区别
当出现类的等号赋值时,会调⽤拷⻉函数,在未定义显示拷⻉构造函数的情况下, 系统会调⽤默认的拷⻉函数-即浅拷⻉,它能够完成成员的⼀⼀复制。当数据成员中没有指针时,浅拷⻉是可⾏的。 但当数据成员中有指针时,如果采⽤简单的浅拷⻉,则两类中的两个指针指向同⼀个地址,当对象快要结束时,会调⽤两次析构函数,⽽导致指野指针的问题。所以,这时必需采⽤深拷⻉。深拷⻉与浅拷⻉之间的区别就在于深拷⻉会在堆内存中另外申请空间来存储数据,从⽽也就解决来野指针的问题。简⽽⾔之,当数据成员中有指针时,必需要⽤深拷⻉更加安全。...原创 2022-05-05 10:42:16 · 175 阅读 · 0 评论 -
函数传递参数的几种方法(值传递、指针传递、引用传递)
·值传递:形参是实参的拷⻉,函数内部对形参的操作并不会影响到外部的实参。 指针传递:也是值传递的⼀种⽅式,形参是指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进⾏操作。 引⽤传递:实际上就是把引⽤对象的地址放在了开辟的栈空间中,函数内部对形参的任何操作可以直接映射到外部的实参上⾯...原创 2022-05-04 15:13:25 · 412 阅读 · 0 评论 -
C++中指针函数和函数指针以及回调函数
指针函数:定义:它的本质是一个函数,不过它的返回值是一个指针。其声明的形式如下所示:ret *func(args, ...);示例:# include <stdio.h># include <stdlib.h>int * func_sum(int n){ if (n < 0) { printf("error:n must be > 0\n"); exit(-1); } stati原创 2022-05-04 15:08:13 · 601 阅读 · 0 评论 -
C++ 中重载和重写,重定义的区别
重载 翻译⾃ overload,是指同⼀可访问区内被声明的⼏个具有不同参数列表的同名函数,依赖于 C++函数名字的修饰 会将参数加在后⾯,可以是参数类型,个数,顺序的不同。根据参数列表决定调⽤哪个函数,重载不关⼼函数的返 回类型。 重写 翻译⾃ override,派⽣类中重新定义⽗类中除了函数体外完全相同的虚函数,注意被重写的函数不能是 static 的, ⼀定要是虚函数,且其他⼀定要完全相同。要注意,重写和被重写的函数是在不同的类当中的,重写函数的访问修 饰符是可以不同的,尽管 vir原创 2022-05-03 11:46:20 · 434 阅读 · 0 评论 -
C 和 C++ 区别 (函数/类/struct/class)
⾸先,C 和 C++ 在基本语句上没有过⼤的区别。 C++ 有新增的语法和关键字,语法的区别有头⽂件的不同和命名空间的不同,C++ 允许我们⾃⼰定义⾃⼰的空间, C 中不可以。关键字⽅⾯⽐如 C++ 与 C 动态管理内存的⽅式不同,C++ 中在 malloc 和 free 的基础上增加了 new 和 delete,⽽且 C++ 中在指针的基础上增加了引⽤的概念,关键字例如 C++中还增加了 auto,explicit 体现显示 和隐式转换上的概念要求,还有 dynamic_cast 增加类型安全⽅⾯原创 2022-05-03 11:41:50 · 718 阅读 · 0 评论 -
C++ 中 const 和 static 关键字(定义,⽤途)
static 作⽤:控制变量的存储⽅式和可⻅性。 作⽤⼀:修饰局部变量:⼀般情况下,对于局部变量在程序中是存放在栈区的,并且局部的⽣命周期在包含语句块 执⾏结束时便结束了。但是如果⽤ static 关键字修饰的话,该变量便会存放在静态数据区,其⽣命周期会⼀直延续 到整个程序执⾏结束。但是要注意的是,虽然⽤ static 对局部变量进⾏修饰之后,其⽣命周期以及存储空间发⽣了 变化,但其作⽤域并没有改变,作⽤域还是限制在其语句块。 作⽤⼆:修饰全部变量:对于⼀个全局变量,它既可以在本⽂件中被访问到,也可原创 2022-05-03 11:37:45 · 802 阅读 · 0 评论 -
C++ 中的指针参数传递和引⽤参数传递
指针参数传递:指针参数传递本质上是值传递,它所传递的是⼀个地址值。值传递过程中,被调函数的形式参数作为被调函数的局部变量处理,会在栈中开辟内存空间以存放由主调函数传递进来的实参值,从⽽形成了实参的⼀个副本(替身)。 值传递的特点是:被调函数对形式参数的任何操作都是作为局部变量进⾏的,不会影响主调函数的实参变ᰁ的值 (形参指针变了,实参指针不会变)。void Swap(int *x, int *y){ int *tmp; tmp = x; x = y; y = tmp;}int m原创 2022-05-03 11:06:01 · 2737 阅读 · 2 评论 -
C++中返回最大最小值的方法--min_element、max_element、max、min(很全)
1. max()使用C++11,需要algorithm标准库两个值的取最大值:max(a,b);多个数取最大值:#include <iostream>#include <algorithm>using namespace std;int main() { int a = 1; int b = 2; int c = 3; cout << max({a, b, c}) << endl; return 0;}2.原创 2022-05-02 16:04:36 · 1625 阅读 · 0 评论 -
C++中emplace_back和push_back区别
emplace_back()是c++11的新特性。区别在于:push_back()方法要调用构造函数和复制构造函数,这也就代表着要先构造一个临时对象,然后把临时的copy构造函数拷贝或者移动到容器最后面。而emplace_back()在实现时,则是直接在容器的尾部创建这个元素,省去了拷贝或移动元素的过程。结论:在C++11情况下,果断用emplace_back代替push_back...原创 2022-04-29 15:35:35 · 858 阅读 · 0 评论 -
C++二维vector初始化
初始化一个 二维vector,行M,列N(行列数确定且含有初始值):// 初始化一个 二维的matrix, 行M,列N,且值为0vector<vector<int>> matrix(M,vector<int>(N));//等价于下面的vector<vector<int> > matrix(M); for(int i=0;i<M;i++) { matrix[i].resize(N);}//等价于下面的vector&l原创 2022-04-29 15:31:26 · 8447 阅读 · 0 评论 -
C++中operator new和placement new
我们写如下代码:A* a = new A;我们知道这里分为三步:1.分配内存,2.调用A()构造对象,3. 返回分配指针。事实上,分配内存这一操作就是由operator new(size_t)来完成的,如果类A重载了operator new,那么将调用A::operator new(size_t ),否则调用全局::operator new(size_t ),后者由C++默认提供。因此前面的步骤也就是:1.调用operator new (sizeof(A))2.调用A:A()3.返回指针原创 2022-04-26 15:00:34 · 193 阅读 · 0 评论 -
C++的空类有哪些成员函数以及类的大小组成
空类的默认成员class Empty{}如果你只是声明一个空类,不做任何事情的话,编译器会自动为你生成一个默认构造函数、一个拷贝默认构造函数、一个默认拷贝赋值操作符、一个默认析构函数、取址运算符和一个取址运算符const。这些函数只有在第一次被调用时,才会别编译器创建。所有这些函数都是inline和public的。class Empty{public:Empty(); // 缺省构造函数//Empty( const Empty& ); // 拷贝构造函数//~Empt原创 2022-04-25 10:54:21 · 1477 阅读 · 1 评论 -
C++中volatile关键字
一、volatile介绍volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。如果没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值。在单任务的环境中,一个函数体内部,如果在两次读取变量的值之间的语句没有对变量的值进行修改,那么编译器就会设法对可执行代码进行优化。由于访问寄存器的速度要快过RAM(从RAM中读取变量的值到寄存器),以后只要变量的值没有改变,就一直从寄存器中读取变量的值原创 2022-04-24 14:41:38 · 835 阅读 · 0 评论 -
C++ 四种强制类型转换
1. C风格的强制转换C风格的强制转换(Type Cast)容易理解,不管什么类型的转换都可以使用使用下面的方式.TypeName b = (TypeName)a;2. C++ 四种强制转换类型函数2.1 const_cast1、常量指针被转化成非常量的指针,并且仍然指向原来的对象;2、常量引用被转换成非常量的引用,并且仍然指向原来的对象;3、const_cast一般用于修改指针。如const char *p形式。const_cast<>里边的内容必须是引用或者指针原创 2022-04-24 14:18:08 · 608 阅读 · 0 评论 -
C++中struct和class区别
在C++中,class和struct做类型定义如下区别:默认继承权限不同,class继承默认是private继承,而struct默认是public继承 class还可用于定义模板参数,像typename,但是关键字struct不能用于定义模板参数C++保留struct关键字,主要有如下原因保证与C语言的向下兼容性,C++必须提供一个struct...原创 2022-04-24 13:50:17 · 1184 阅读 · 0 评论 -
C++之max_element和min_element
头文件:#include<algorithm>作用:返回容器中最小值和最大值的指针。max_element(first,end,cmp);其中cmp为可选择参数!vector<cv::DMatch> matches;cv::BFMatcher matcher ( cv::NORM_HAMMING );matcher.match ( descriptors_ref_, descriptors_curr_, matches );// select the best mat原创 2022-04-24 13:48:39 · 537 阅读 · 0 评论 -
C++中覆盖和重载的区别
覆盖是指派生类中重新定义的函数,其函数名、参数列表、返回类型与父类完全相同,只是函数体存在区别;覆盖只发生在类的成员函数中;重载是指两个函数具有相同的函数名,不同的参数列表,不关心返回值;当调用函数时,根据传递的参数列表来判断调用哪个函数;重载可以是类的成员函数,也可以是普通函数。...原创 2022-04-23 11:22:26 · 1055 阅读 · 0 评论