C++
文章平均质量分 63
主要讲解C++一些基础的、常用的知识点,以及C++11的新特性。
灬Sunnnnn
承接各种定制开发,Qt、音视频、流媒体、客户端、服务端,需要的私聊。
展开
-
C++ 必备知识点(一看秒懂),逆袭进大厂,干货满满,全在这里
本文主要对C++一些必备知识点的梳理,适合在校学生、有意向跳槽的,工作经验不足的人群。更有C++11 常用的特性知识梳理。知识梳理C++ new关键字详解 C++ 深拷贝和浅拷贝 C++ 静态库和动态库 C++ new和malloc的区别详解 C++ 宏定义和typedef区别详解 C++ strlen和sizeof区别 C++ 野指针和悬空指针 C++ struct和class的区别 C++ static关键字的作用原创 2021-05-05 11:13:15 · 937 阅读 · 2 评论 -
C++ 内联函数(秒懂)
内联函数函数是一个可以重复使用的代码块,CPU 会一条一条地挨着执行其中的代码。CPU 在执行主调函数代码时如果遇到了被调函数,主调函数就会暂停,CPU 转而执行被调函数的代码;被调函数执行完毕后再返回到主调函数,主调函数根据刚才的状态继续往下执行。一个 C/C++程序的执行过程可以认为是多个函数之间的相互调用过程,它们形成了一个或简单或复杂的调用链条,这个链条的起点是 main(),终点也是 main()。当 main() 调用完了所有的函数,它会返回一个值(例如return 0;)来结束自己的生命原创 2021-04-30 15:39:01 · 28154 阅读 · 16 评论 -
C++ 重载、重写(覆盖)和隐藏的区别
重载(overload)重载是指在同一范围定义中的同名成员函数才存在重载关系。主要特点是函数名相同,参数类型和数目有所不同,不能出现参数个数和类型均相同,仅仅依靠返回值不同来区分的函数。重载和函数成员是否是虚函数无关。举个例子:classA{...virtualintfun();voidfun(int);voidfun(double,double);staticintfun(char);...}重写(覆盖)(over...原创 2021-04-26 21:36:26 · 893 阅读 · 0 评论 -
C++11多线程并发基础知识
C++多线程并发基础知识1.创建线程首先要引入头文件#include<thread>,C++11中管理线程的函数和类在该头文件中声明,其中包括std::thread类。例:std::thread th1(proc1)创建了一个名为th1的线程,并且线程th1开始执行。实例化std::thread类对象时,至少需要传递函数名作为参数。如果函数为有参函数,如 void proc2(int a,int b),那么实例化std::thread类对象时,则需要传递更多参数,参数顺序依次为函原创 2021-04-23 17:09:57 · 754 阅读 · 2 评论 -
C++11 智能指针
一.简介C++的入门坑点大家都是有目共睹的,无非就是指针的理解不深导致一些野指针,内存泄露等问题,所以就不赘述。智能指针正好能够弥补这些问题,因为它本质是存放在栈的模板对象,只是在栈内部包了一层指针。而栈在其生命周期结束时,其中的指针指向的堆内存也自然被释放了。因而实现了智能管理的效果,不需要考虑内存问题了,其实有点类似某种单例写法,程序运行结束,也不用考虑单例对象内存问题。c++11...原创 2019-12-17 22:35:35 · 483 阅读 · 0 评论 -
C++ 友元函数和友元类(C++ friend关键字)
在C++中,一个类中可以有 public、protected、private 三种属性的成员,通过对象可以访问 public 成员,只有本类中的函数可以访问本类的 private 成员。现在,我们来介绍一种例外情况——友元(friend)。借助友元(friend),可以使得其他类中的成员函数以及全局范围内的函数访问当前类的 private 成员。friend 的意思是朋友,或者说是好友,与好友的关系显然要比一般人亲密一些。我们会对好朋友敞开心扉,倾诉自己的秘密,而对一般人会谨言慎行,潜意识里就自我保护。在原创 2021-05-05 12:03:45 · 1572 阅读 · 0 评论 -
C++ 纯虚函数和抽象类详解
在C++中,可以将虚函数声明为纯虚函数,语法格式为:virtual 返回值类型 函数名 (函数参数) = 0;纯虚函数没有函数体,只有函数声明,在虚函数声明的结尾加上=0,表明此函数为纯虚函数,最后的=0并不表示函数返回值为0,它只起形式上的作用,告诉编译系统“这是纯虚函数”。抽象类(Abstract Class):包含纯虚函数的类,之所以说它抽象,是因为它无法实例化,也就是无法创建对象。原因很明显,纯虚函数没有函数体,不是完整的函数,无法调用,也无法为其分配内存空间。抽象类通常是作为基类.原创 2021-05-05 11:46:44 · 1176 阅读 · 0 评论 -
C++ 虚继承和虚基类详解
多继承(Multiple Inheritance)多继承:是指从多个直接基类中产生派生类的能力,多继承的派生类继承了所有父类的成员。尽管概念上非常简单,但是多个基类的相互交织可能会带来错综复杂的设计问题,命名冲突就是不可回避的一个。多继承时很容易产生命名冲突,即使我们很小心地将所有类中的成员变量和成员函数都命名为不同的名字,命名冲突依然有可能发生,比如典型的是菱形继承,如下图所示:菱形继承类 A 派生出类 B 和类 C,类 D 继承自类 B 和类 C,这个时候类 A 中的..原创 2021-05-05 11:37:25 · 430 阅读 · 0 评论 -
C++11 完美转发
C++11 标准为 C++ 引入右值引用语法的同时,还解决了一个 C++ 98/03 标准长期存在的短板,即使用简单的方式即可在函数模板中实现参数的完美转发。那么,什么是完美转发?完美转发:它指的是函数模板可以将自己的参数“完美”地转发给内部调用的其它函数。所谓完美,即不仅能准确地转发参数的值,还能保证被转发参数的左、右值属性不变。举个例子:template<typename T>void function(T t) { otherdef(t);}如上所示,funct原创 2021-04-30 14:29:33 · 1122 阅读 · 3 评论 -
C++11 移动构造函数详解
C++11移动语义是什么在 C++ 11 标准之前(C++ 98/03 标准中),如果想用其它对象初始化一个同类的新对象,只能借助类中的复制(拷贝)构造函数。通过C++拷贝构造函数一节的学习我们知道,拷贝构造函数的实现原理很简单,就是为新对象复制一份和其它对象一模一样的数据。需要注意的是,当类中拥有指针类型的成员变量时,拷贝构造函数中需要以深拷贝(而非浅拷贝)的方式复制该指针成员。举个例子:#include <iostream>using namespace std;cl原创 2021-04-27 10:32:41 · 2238 阅读 · 2 评论 -
C++11 右值引用(一看即懂)
C++左值和右值右值引用可以从字面意思上理解,指的是以引用传递(而非值传递)的方式使用 C++ 右值。在 C++ 或者 C 语言中,一个表达式(可以是字面量、变量、对象、函数的返回值等)根据其使用场景不同,分为左值表达式和右值表达式。确切的说 C++ 中左值和右值的概念是从 C 语言继承过来的。值得一提的是,左值的英文简写为“lvalue”,右值的英文简写为“rvalue”。很多人认为它们分别是"left value"、"right value" 的缩写,其实不然。lvalue 是“loacto原创 2021-04-26 22:48:03 · 3854 阅读 · 4 评论 -
C++11 constexpr和const的区别详解
我们知道,constexpr 是 C++ 11 标准新添加的关键字,在此之前(C++ 98/03标准)只有 const 关键字,其在实际使用中经常会表现出两种不同的语义。举个例子:#include <iostream>#include <array>using namespace std;void dis_1(const int x){ //错误,x是只读的变量 array <int,x> myarr{1,2,3,4,5}; cou原创 2021-04-26 22:35:15 · 5880 阅读 · 5 评论 -
C++11 constexpr关键字
constexpr 是 C++ 11 标准新引入的关键字,不过在讲解其具体用法和功能之前,读者需要先搞清楚 C++ 常量表达式的含义。所谓常量表达式:指的就是由多个(≥1)常量组成的表达式。换句话说,如果表达式中的成员都是常量,那么该表达式就是一个常量表达式。这也意味着,常量表达式一旦确定,其值将无法修改。实际开发中,我们经常会用到常量表达式。以定义数组为例,数组的长度就必须是一个常量表达式:int url[10];//正确int url[6 + 4];//正确int length = 6;原创 2021-04-26 22:30:19 · 1624 阅读 · 0 评论 -
C++11 for循环(基于范围的循环)详解
C++ 11标准之前(C++ 98/03 标准),如果要用 for 循环语句遍历一个数组或者容器,只能套用如下结构:for(表达式 1; 表达式 2; 表达式 3){ //循环体}例如,下面程序演示了用上述结构遍历数组和容器的具体实现过程(实例一):#include <iostream>#include <vector>#include <string.h>using namespace std;int main() { ch...原创 2021-04-26 22:08:51 · 3393 阅读 · 0 评论 -
C++11 列表初始化
我们知道,在 C++98/03 中的对象初始化方法有很多种,请看下面的代码://初始化列表int i_arr[3] = { 1, 2, 3 }; //普通数组struct A{ int x; struct B { int i; int j; } b;} a = { 1, { 2, 3 } }; //POD类型//拷贝初始化(copy-initialization)int i = 0;class Foo{public:原创 2021-04-26 22:01:00 · 637 阅读 · 0 评论 -
C++11 使用using定义别名(替代typedef)
大家都知道,C++中可以通过 typedef 重定义一个类型:typedef unsigned int uint_t;被重定义的类型并不是一个新的类型,仅仅只是原有的类型取了一个新的名字。因此,下面这样将不是合法的函数重载:void func(unsigned int);void func(uint_t); // error: redefinition使用 typedef 重定义类型是很方便的,但它也有一些限制,比如,无法重定义一个模板。想象下面这个场景:typedef st.原创 2021-04-26 21:54:19 · 2734 阅读 · 1 评论 -
C++11 返回值类型后置(跟踪返回值类型)
在泛型编程中,可能需要通过参数的运算来得到返回值的类型。考虑下面这个场景:template <typename R, typename T, typename U>R add(T t, U u){ return t+u;}int a = 1;float b = 2.0;auto c = add<decltype(a + b)>(a, b);我们并不关心 a+b 的类型是什么,因此,只需要通过 decltype(a+b) 直接得到返回值类型即可。但是像原创 2021-04-26 21:47:22 · 934 阅读 · 0 评论 -
C++11 decltype类型推导详解
decltype decltype 是 C++11 新增的一个关键字,它和 auto 的功能一样,都用来在编译时期进行自动类型推导。decltype 是“declare type”的缩写,译为“声明类型”。既然已经有了 auto 关键字,为什么还需要 decltype 关键字呢?因为 auto 并不适用于所有的自动类型推导场景,在某些特殊情况下 auto 用起来非常不方便,甚至压根无法使用,所以 decltype 关键字也被引入到 C++11 中。auto 和 decltype 关键字都可以自原创 2021-04-26 21:35:10 · 2158 阅读 · 0 评论 -
C++11 auto关键字详解
在C++11 之前的版本(C++98 和 C++ 03)中,定义变量或者声明变量之前都必须指明它的类型,比如 int、char 等;程序员在定义变量时可以不指明具体的类型,而是让编译器(或者解释器)自己去推导,这就让代码的编写更加方便。C++11 为了顺应这种趋势也开始支持自动类型推导了!C++11 使用auto关键字来支持自动类型推导。auto 类型推导的语法和规则在之前的 C++ 版本中,auto 关键字用来指明变量的存储类型,它和 static 关键字是相对的。auto 表示变量是自动存..原创 2021-04-26 16:44:42 · 2201 阅读 · 0 评论 -
C++ 为什么析构函数一般写成虚函数
由于类的多态性,基类指针可以指向派生类的对象,如果删除该基类的指针,就会调用该指针指向的派生类析构函数,而派生类的析构函数又自动调用基类的析构函数,这样整个派生类的对象完全被释放。如果析构函数不被声明成虚函数,则编译器实施静态绑定,在删除基类指针时,只会调用基类的析构函数而不调用派生类析构函数,这样就会造成派生类对象析构不完全,造成内存泄漏。所以将析构函数声明为虚函数是十分必要的。在实现多态时,当用基类操作派生类,在析构时防止只析构基类而不析构派生类的状况发生,要将基类的析构函数声明为虚函数。举个例子:原创 2021-04-25 21:33:24 · 1379 阅读 · 0 评论 -
C++ extern“C“的用法
为了能够正确的在C++代码中调用C语言的代码:在程序中加上extern "C"后,相当于告诉编译器这部分代码是C语言写的,因此要按照C语言进行编译,而不是C++;哪些情况下使用extern "C":(1)C++代码中调用C语言代码;(2)在C++中的头文件中使用;(3)在多个人协同开发时,可能有人擅长C语言,而有人擅长C++;举个例子,C++中调用C代码:#ifndef__MY_HANDLE_H__#define__MY_HANDLE_H__extern"C"{...原创 2021-04-25 21:29:45 · 807 阅读 · 0 评论 -
C++ final和override关键字
override当在父类中使用了虚函数时候,你可能需要在某个子类中对这个虚函数进行重写,以下方法都可以:classA{virtualvoidfoo();}classB:publicA{voidfoo();//OKvirtualvoidfoo();//OKvoidfoo()override;//OK}如果不使用override,当你手一抖,将foo()写成了foo()会怎么样呢?结果是编译器并不会报错,因为它并不知...原创 2021-04-25 21:25:42 · 319 阅读 · 0 评论 -
C++ const关键字的作用
不考虑类的情况:const常量在定义时必须初始化,之后无法更改 const形参可以接收const和非const类型的实参,例如//i可以是int型或者constint型voidfun(constint&i){//...}考虑类的情况:const成员变量:不能在类定义外部初始化,只能通过构造函数初始化列表进行初始化,并且必须有构造函数;不同类对其const数据成员的值可以不同,所以不能在类中声明时初始化。 const成员函数:const对象不可以调...原创 2021-04-25 21:16:52 · 3273 阅读 · 0 评论 -
C++ static关键字的作用
不考虑类的情况:隐藏。所有不加static的全局变量和函数具有全局可见性,可以在其他文件中使用,加了之后只能在该文件所在的编译模块中使用 默认初始化为0,包括未初始化的全局静态变量与局部静态变量,都存在全局未初始化区 静态变量在函数内定义,始终存在,且只进行一次初始化,具有记忆性,其作用范围与局部变量相同,函数退出后仍然存在,但不能使用考虑类的情况:static成员变量:只与类关联,不与类的对象关联。定义时要分配空间,不能在类声明中初始化,必须在类定义体外部初始化,初始化时不需要标示为stat原创 2021-04-25 21:14:36 · 346 阅读 · 0 评论 -
C++ struct和class的区别
1.相同点两者都拥有成员函数、公有和私有部分任何可以使用class完成的工作,同样可以使用struct完成2.不同点两者中如果不对成员不指定公私有,struct默认是公有的,class则默认是私有的 class默认是private继承,而struct模式是public继承 class可以作为模板类型,struct不行引申:C++和C的struct区别C中:struct是用户自定义数据类型(UDT);C++中struct是抽象数据类型(ADT),支持成员函数的定义,(C++中的s原创 2021-04-25 21:12:08 · 436 阅读 · 0 评论 -
C++ 野指针和悬空指针
都是是指向无效内存区域(这里的无效指的是"不安全不可控")的指针,访问行为将会导致未定义行为。野指针:指的是没有被初始化过的指针。intmain(void){int*p;std::cout<<*p<<std::endl; return 0;}因此,为了防止出错,对于指针初始化时都是赋值为nullptr,这样在使用时编译器就会直接报错,产生非法内存访问。悬空指针:指针最初指向的内存已经被释放了的一种指针。int main(void)...原创 2021-04-25 21:08:14 · 1821 阅读 · 1 评论 -
C++ strlen和sizeof区别
sizeof是运算符,并不是函数,结果在编译时得到而非运行中获得;strlen是字符处理的库函数。 sizeof参数可以是任何数据的类型或者数据(sizeof参数不退化);strlen的参数只能是字符指针且结尾是'\0'的字符串。 因为sizeof值在编译时确定,所以不能用来得到动态分配(运行时分配)存储空间的大小。 const char* str = "name"; sizeof(str); // 取的是指针str的长度,是8 strlen(str); /.原创 2021-04-25 21:04:38 · 2745 阅读 · 5 评论 -
C++ 宏定义和typedef区别详解
宏主要用于定义常量及书写复杂的内容;typedef主要用于定义类型别名。 宏替换发生在编译阶段之前,属于文本插入替换;typedef是编译的一部分。 宏不检查类型;typedef会检查数据类型。 宏不是语句,不在在最后加分号;typedef是语句,要加分号标识结束。 注意对指针的操作,typedef char * p_char和#define p_char char *区别巨大。...原创 2021-04-25 21:01:43 · 1867 阅读 · 1 评论 -
C++ new和malloc的区别详解
malloc和free是标准库函数,支持覆盖;new和delete是运算符,并且支持重载。 malloc仅仅分配内存空间,不具备调用构造函数功能;new除了分配空间外,还会调用构造函数。 malloc分配内存失败时返回NULL;new内存分配失败时,会抛出bac_alloc异常。 malloc返回的是void类型指针(必须进行类型转换),new返回的是具体类型指针。 malloc需要显式地指出所需内存的尺寸,使用new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计算。 new原创 2021-04-25 20:59:22 · 1632 阅读 · 0 评论 -
C++ 静态库和动态库
目标文件在解释静态库和动态库之前,需要简单了解一下什么是目标文件。目标文件常常按照特定格式来组织,在linux下,它是ELF格式(Executable Linkable Format,可执行可链接格式),而在windows下是PE(Portable Executable,可移植可执行)。而通常目标文件有三种形式:可执行目标文件。即我们通常所认识的,可直接运行的二进制文件。 可重定位目标文件。包含了二进制的代码和数据,可以与其他可重定位目标文件合并,并创建一个可执行目标文件。 共享目标文件。它原创 2021-04-23 15:49:20 · 544 阅读 · 0 评论 -
C++面试题
构造函数不能声明为虚函数的原因是:构造一个对象的时候,必须知道对象的实际类型,而虚函数行为是在运行期间确定实际类型的。而在构造一个对象时,由于对象还未构造成功。编译器无法知道对象的实际类型,是该类本身,还是该类的一个派生类,或是更深层次的派生类。无法确定。。。虚函数的意思就是开启动态绑定,程序会根据对象的动态类型来选择要调用的方法。然而在构造函数运行的时候,这个对象的动态类型还不完整,没有办...原创 2020-04-04 16:35:40 · 187 阅读 · 0 评论 -
C++ STL容器简介
1.容器分类STL序列容器:vector、string、deque、listSTL关联容器:set、multiset、map、multimapSTL适配容器:stack、queue、priority_queue2.容器简介1.vectorvector内部是使用动态数组的方式实现的,如果动态数组的内存不够用,就要动态地重新分配,一般是当前大小的两倍,然后把原数组的...原创 2020-03-01 21:46:09 · 268 阅读 · 0 评论 -
C++ i++ 和 ++i哪个效率更高
先看以下代码1 #include <stdio.h>23 int main()4 {5 int i = 0;6 int x = 0;78 i++;9 ++i;10 x = i++;11 x = ++i;1213 return 0;14 ...原创 2020-03-01 16:56:20 · 844 阅读 · 0 评论 -
C++ 指针和引用区别详解
1.初始化要求不同。引用在创建的同时必须初始化,即引用到一个有效的对象;而指针在定义的时候不必初始化,可以在定义后面的任何地方重新赋值。2.可修改性不同。引用一旦被初始化为指向一个对象,它就不能被改变为另外一个对象的引用;而指针在任何时候都可以改变为指向另外一个对象。给引用赋值并不是改变它和原始对象的绑定关系。3.不存在NULL引用,引用不能使用指向空值的引用,它必须总是指向某个对象;而指...原创 2020-03-01 16:41:46 · 869 阅读 · 0 评论 -
C++ 强制类型转换
一.强制类型转换C++语言中提供了static_cast、const_cast、reinterpret_cast和dynamic_cast。这四个关键字都是用于强制类型转换的。二.static_cast1.基本数据之间的转换,如int转化为doubleint a = 1;double b = static_cast<double>(a);2.用于类...原创 2020-01-07 21:00:07 · 2657 阅读 · 0 评论 -
C++ 11新特性
constexpr关键字常量表达式给编译器提供了优化的机会, 编译器计算出他们的值并把结果硬编码到程序中. 例如,定义一个数组需要常量表达式(来指定数组大小), 枚举值必须是常量表达式. 然而,常量表达式中从来都不允许调用函数或创建对象. 所以,像下面这样的简单代码却是非法的:int get_five() {return 5;} int some_value[get_five() ...原创 2019-12-24 22:40:41 · 1312 阅读 · 0 评论 -
C++ 深拷贝和浅拷贝
1.浅拷贝只是增加了一个指针指向已经存在的内存。2.深拷贝就是增加一个指针并且申请一个新的内存,使这个增加的指针指向这个新的内存。3.采用深拷贝的情况下,释放内存的时候就不会出现在浅拷贝时重复释放同一内存的错误。我列举一个例子来说吧:你正在编写C++中有时用到,操作符的重载。最能体现深层拷贝与浅层拷贝的,就是‘=’的重载。看下面一个简单的程序:class string{...原创 2019-12-17 21:03:44 · 744 阅读 · 1 评论 -
C++ new关键字详解
一.new的基本用法1.c++通过new关键字进行动态分配内存。2.new开辟的空间存储在堆上,而我们定义的变量存储在栈上。3.new分配的空间使用delete释放,new[] 使用 delete[]。4.int* pi = new int(5);//表示动态分配一个int ,初始化为 5int* pa = new int[5];//表示动态分配一个数组,数组大小为5...原创 2019-12-17 20:25:03 · 28010 阅读 · 3 评论