![](https://img-blog.csdnimg.cn/20201014180756757.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
C++
文章平均质量分 71
C++笔记
Hardy20200507
树立终生学习理念,付诸行动。
展开
-
在C++程序中调用被C编译器编译后的函数,为什么要加extern “C“
C++语言支持函数重载,C语言不支持函数重载,函数被C++编译器编译后在库中的名字与C语言不同,假设某个函数原型为:void foo(int x,int y);该函数被C编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字,为了解决此类名字匹配的问题,C++提供了C链接库交换指定符号extern “C”...原创 2022-04-02 09:38:49 · 932 阅读 · 0 评论 -
C++内存管理
C++内存分区:栈、堆、全局/静态存储区、常量存储区、代码区。栈:存放函数的局部变量、函数参数、返回地址等,由编译器自动分配和释放。堆:动态申请的内存空间,就是由 malloc 分配的内存块,由程序员控制它的分配和释放,如果程序执行结束还没有释放,操作系统会自动回收。全局区/静态存储区(.bss 段和 .data 段):存放全局变量和静态变量,程序运行结束操作系统自动释放,在 C 语言中,未初始化的放在 .bss 段中,初始化的放在 .data 段中,C++ 中不再区分了。常量存储区(.data 段原创 2022-04-02 08:52:12 · 219 阅读 · 0 评论 -
C++11完美转发及其实现
首先解释一下什么是完美转发,它指的是函数模板可以将自己的参数“完美”地转发给内部调用的其它函数。所谓完美,即不仅能准确地转发参数的值,还能保证被转发参数的左、右值属性不变。举个例子:template<typename T>void function(T t) { otherdef(t);}如上所示,function() 函数模板中调用了 otherdef() 函数。在此基础上,完美转发指的是:如果 function() 函数接收到的参数 t 为左值,那么该函数传递给 othe转载 2022-03-06 22:27:42 · 245 阅读 · 0 评论 -
C++11引用限定符的用法
**默认情况下,对于类中用 public 修饰的成员函数,既可以被左值对象调用,也可以被右值对象调用。**举个例子:#include <iostream>using namespace std;class demo {public: demo(int num):num(num){} int get_num(){ return this->num; }private: int num;};int main() { demo转载 2022-03-06 22:00:20 · 107 阅读 · 0 评论 -
C++11 move()函数:将左值强制转换为右值
C++11 标准中借助右值引用可以为指定类添加移动构造函数,这样当使用该类的右值对象(可以理解为临时对象)初始化同类对象时,编译器会优先选择移动构造函数。注意,移动构造函数的调用时机是:用同类的右值对象初始化新对象。那么,用当前类的左值对象(有名称,能获取其存储地址的实例对象)初始化同类对象时,是否就无法调用移动构造函数了呢?当然不是,C++11 标准中已经给出了解决方案,即调用 move() 函数。move 本意为 “移动”,但该函数并不能移动任何数据,它的功能很简单,就是将某个左值强制转化为右值。转载 2022-03-06 21:28:48 · 108 阅读 · 0 评论 -
C++11移动构造函数的功能和用法
C++11移动语义是什么在 C++ 11 标准之前(C++ 98/03 标准中),如果想用其它对象初始化一个同类的新对象,只能借助类中的复制(拷贝)构造函数。拷贝构造函数的实现原理很简单,就是为新对象复制一份和其它对象一模一样的数据。需要注意的是,当类中拥有指针类型的成员变量时,拷贝构造函数中需要以深拷贝(而非浅拷贝)的方式复制该指针成员。#include <iostream>using namespace std;class demo{public: demo():num转载 2022-03-06 20:02:31 · 841 阅读 · 1 评论 -
C++11右值引用
C++左值和右值右值引用可以从字面意思上理解,指的是以引用传递(而非值传递)的方式使用 C++ 右值。在 C++ 或者 C 语言中,一个表达式(可以是字面量、变量、对象、函数的返回值等)根据其使用场景不同,分为左值表达式和右值表达式。确切的说 C++ 中左值和右值的概念是从 C 语言继承过来的。值得一提的是,左值的英文简写为“lvalue”,右值的英文简写为“rvalue”。很多人认为它们分别是"left value"、“right value” 的缩写,其实不然。lvalue 是“loactor转载 2022-03-06 19:02:47 · 71 阅读 · 0 评论 -
C++11 constexpr:验证是否为常量表达式及与const的区别
constexpr 是 C++ 11 标准新引入的关键字,不过在讲解其具体用法和功能之前,读者需要先搞清楚 C++ 常量表达式的含义。所谓常量表达式,指的就是由多个(≥1)常量组成的表达式。换句话说,如果表达式中的成员都是常量,那么该表达式就是一个常量表达式。这也意味着,常量表达式一旦确定,其值将无法修改。实际开发中,我们经常会用到常量表达式。以定义数组为例,数组的长度就必须是一个常量表达式:// 1)int url[10];//正确// 2)int url[6 + 4];//正确// 3)转载 2022-03-06 12:48:59 · 130 阅读 · 0 评论 -
C++11非受限联合体(union)
在 C/C++ 中,联合体(Union)是一种构造数据类型。在一个联合体内,我们可以定义多个不同类型的成员,这些成员将会共享同一块内存空间。老版本的 C++ 为了和C语言保持兼容,对联合体的数据成员的类型进行了很大程度的限制,这些限制在今天看来并没有必要,因此 C++11 取消了这些限制。C++11 标准规定,任何非引用类型都可以成为联合体的数据成员,这种联合体也被称为非受限联合体。例如:class Student{public: Student(bool g, int a): gender(转载 2022-03-06 10:43:26 · 136 阅读 · 0 评论 -
C++11 tuple元组详解
C++11 标准新引入了一种类模板,命名为 tuple(中文可直译为元组)。tuple 最大的特点是:实例化的对象可以存储任意数量、任意类型的数据。tuple 的应用场景很广泛,例如当需要存储多个不同类型的元素时,可以使用 tuple;当函数需要返回多个数据时,可以将这些数据存储在 tuple 中,函数只需返回一个 tuple 对象即可。tuple对象的创建tuple 本质是一个以可变模板参数定义的类模板,它定义在 头文件并位于 std 命名空间中。因此要想使用 tuple 类模板,程序中需要首先引转载 2022-03-05 21:16:46 · 1283 阅读 · 0 评论 -
C++11在函数模板和类模板中使用可变参数
参考文献1、http://c.biancheng.net/view/vip_8692.html所谓可变参数,指的是参数的个数和类型都可以是任意的。对于函数参数而言,C++ 一直都支持为函数设置可变参数,最典型的代表就是 printf() 函数,它的语法格式为:int printf ( const char * format, ... );…就表示的是可变参数,即 printf() 函数可以接收任意个参数,且各个参数的类型可以不同,例如:printf("%d", 10);printf("%d转载 2022-03-05 14:44:09 · 832 阅读 · 0 评论 -
C++11支持函数模板的默认模板参数
参考文献1、http://c.biancheng.net/view/3734.html在 C++98/03 标准中,类模板可以有默认的模板参数,如下:template <typename T, typename U = int, U N = 0>struct Foo{ // ...};但是却不支持函数的默认模板参数:template <typename T = int> // error in C++98/03: default template argu转载 2022-03-05 12:45:59 · 79 阅读 · 0 评论 -
C++11使用using定义别名(替代typedef)
参考文献1、http://c.biancheng.net/view/3730.html在 C++ 中可以通过 typedef 重定义一个类型:typedef unsigned int uint_t;被重定义的类型并不是一个新的类型,仅仅只是原有的类型取了一个新的名字。因此,下面这样将不是合法的函数重载:void func(unsigned int);void func(uint_t); // error: redefinition使用 typedef 重定义类型是很方便的,但它也有一些限转载 2022-03-05 12:25:28 · 77 阅读 · 0 评论 -
C++11对模板实例化中连续右尖括号>>的改进
参考文献1、http://c.biancheng.net/view/vip_3729.html在 C++98/03 的泛型编程中,模板实例化有一个很烦琐的地方,那就是连续两个右尖括号(>>)会被编译器解释成右移操作符,而不是模板参数表的结束。【实例】C++98/03 中不支持连续两个右尖括号的示例。纯文本复制template <typename T>struct Foo{ typedef T type;};template <typename T&转载 2022-03-05 10:29:26 · 412 阅读 · 0 评论 -
C++返回值类型后置(跟踪返回值类型)
在泛型编程中,可能需要通过参数的运算来得到返回值的类型。考虑下面这个场景: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);...转载 2022-03-05 10:03:33 · 83 阅读 · 0 评论 -
汇总auto和decltype的区别
参考文献http://c.biancheng.net/view/vip_8670.html语法格式的区别auto 和 decltype 都是 C++11 新增的关键字,都用于自动类型推导,但是它们的语法格式是有区别的,如下所示:auto varname = value; //auto的语法格式decltype(exp) varname [= value]; //decltype的语法格式其中,varname 表示变量名,value 表示赋给变量的值,exp 表示一个表达式,方括号[ ]表示转载 2022-02-27 08:51:03 · 419 阅读 · 0 评论 -
C++11列表初始化(统一了初始化方式)
参考文献http://c.biancheng.net/view/3737.html我们知道,在 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-initi转载 2022-02-27 08:29:30 · 118 阅读 · 0 评论 -
C++11 for循环(基于范围的循环)
参考文献1、http://c.biancheng.net/view/7759.html2、http://c.biancheng.net/view/vip_7760.htmlC++11 for循环(基于范围的循环)C++ 11标准之前(C++ 98/03 标准),如果要用 for 循环语句遍历一个数组或者容器,只能套用如下结构:for(表达式 1; 表达式 2; 表达式 3){ //循环体}而 C++ 11 标准中,除了可以沿用前面介绍的用法外,还为 for 循环添加了一种全新的语法格转载 2022-02-27 08:29:07 · 167 阅读 · 0 评论 -
C++11 shared_ptr智能指针
转载自http://c.biancheng.net/view/7898.html在实际的 C++ 开发中,我们经常会遇到诸如程序运行中突然崩溃、程序运行所用内存越来越多最终不得不重启等问题,这些问题往往都是内存资源管理不当造成的。比如:有些内存资源已经被释放,但指向它的指针并没有改变指向(成为了野指针),并且后续还在使用;有些内存资源已经被释放,后期又试图再释放一次(重复释放同一块内存会导致程序运行崩溃);没有及时释放不再使用的内存资源,造成内存泄漏,程序占用的内存资源越来越多。针对以上这些情况转载 2022-02-27 08:28:40 · 74 阅读 · 0 评论 -
C++11 unique_ptr智能指针
转载1、http://c.biancheng.net/view/vip_8672.html作为智能指针的一种,unique_ptr 指针自然也具备“在适当时机自动释放堆内存空间”的能力。和 shared_ptr 指针最大的不同之处在于,unique_ptr 指针指向的堆内存无法同其它 unique_ptr 共享,也就是说,每个 unique_ptr 指针都独自拥有对其所指堆内存空间的所有权。这也就意味着,每个 unique_ptr 指针指向的堆内存空间的引用计数,都只能为 1,一旦该 unique_p转载 2022-02-27 08:28:18 · 97 阅读 · 0 评论 -
C++11 weak_ptr智能指针
http://c.biancheng.net/view/vip_8673.htmlC++11 weak_ptr智能指针和 shared_ptr、unique_ptr 类型指针一样,weak_ptr 智能指针也是以模板类的方式实现的。weak_ptr( T 为指针所指数据的类型)定义在头文件,并位于 std 命名空间中。因此,要想使用 weak_ptr 类型指针,程序中应首先包含如下 2 条语句:#include <memory>using namespace std;第 2 句并不是转载 2022-02-27 08:27:51 · 67 阅读 · 0 评论 -
C++11 nullptr:初始化空指针
转载http://c.biancheng.net/view/7887.html实际开发中,避免产生“野指针”最有效的方法,就是在定义指针的同时完成初始化操作,即便该指针的指向尚未明确,也要将其初始化为空指针。所谓“野指针”,又称“悬挂指针”,指的是没有明确指向的指针。野指针往往指向的是那些不可用的内存区域,这就意味着像操作普通指针那样使用野指针(例如 &p),极可能导致程序发生异常。C++98/03 标准中,将一个指针初始化为空指针的方式有 2 种:int *p = 0;int *p =转载 2022-02-27 08:27:18 · 280 阅读 · 0 评论 -
C++ auto类型推导
参考文献http://c.biancheng.net/view/6984.htmlauto 类型推导的语法和规则在之前的 C++ 版本中,auto 关键字用来指明变量的存储类型,它和 static 关键字是相对的。auto 表示变量是自动存储的,这也是编译器的默认规则,所以写不写都一样,一般我们也不写,这使得 auto 关键字的存在变得非常鸡肋。C++11 赋予 auto 关键字新的含义,使用它来做自动类型推导。也就是说,使用了 auto 关键字以后,编译器会在编译期间自动推导出变量的类型,这样我们转载 2022-02-27 08:26:47 · 120 阅读 · 0 评论 -
C++ decltype类型推导
参考文献1、http://c.biancheng.net/view/7151.htmlauto 和 decltype 关键字都可以自动推导出变量的类型,但它们的用法是有区别的:auto varname = value;decltype(exp) varname = value;其中,varname 表示变量名,value 表示赋给变量的值,exp 表示一个表达式。auto 根据=右边的初始值 value 推导出变量的类型,而 decltype 根据 exp 表达式推导出变量的类型,跟=右边的转载 2022-02-27 08:26:28 · 105 阅读 · 0 评论 -
C++11 lambda匿名函数用法详解
转载自1、http://c.biancheng.net/view/7818.htmllambda 源自希腊字母表中第 11 位的 λ,在计算机科学领域,它则是被用来表示一种匿名函数。所谓匿名函数,简单地理解就是没有名称的函数,又常被称为 lambda 函数或者 lambda 表达式。lambda匿名函数的定义定义一个 lambda 匿名函数很简单,可以套用如下的语法格式:[外部变量访问方式说明符] (参数) mutable noexcept/throw() -> 返回值类型{ 函数体转载 2022-02-25 09:19:03 · 401 阅读 · 0 评论 -
C++虚析构与纯虚析构
C++虚析构与纯虚析构多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用子类的析构代码解决方法:将父类中的析构函数改为虚析构或纯虚析构纯虚析构和虚析构共性:1、可以解决父类指针释放子类对象的问题;2、都需要具体的函数实现;纯虚析构是类内声明,类外实现。纯虚析构和虚析构区别:如果是纯虚析构,该类属于抽象类,无法实例化对象虚析构语法:virtual ~类名(){ //code}纯虚析构语法virtual ~类名()= 0;//类内声明//类外实现类名:原创 2021-03-15 22:34:17 · 190 阅读 · 1 评论 -
C++虚函数与纯虚函数
C++虚函数与纯虚函数多态是C++面向对象的三大特性之一。多态分为两类1、静态多态函数重载、运算符重载属于静态多态,复用函数名2、动态多态派生类或虚函数运行时多态静态多态和动态多态的区别1、静态多态的函数地址早绑定,编译阶段确定函数地址;2、动态多态的函数地址晚绑定,运行阶段确定函数地址;虚函数动态多态的满足条件:1、有继承关系;2、子类重写父类的函数动态多态使用父类的指针或引用指向子类对象#include <iostream>#include <stri原创 2021-03-15 20:56:45 · 103 阅读 · 0 评论 -
C++中的浅拷贝与深拷贝
浅拷贝:简单的赋值拷贝操作。深拷贝:在堆区重新申请空间,进行拷贝操作。浅拷贝带来的问题就是堆区的内存重复释放的问题,浅拷贝的问题要用深拷贝去解决。#include <iostream>using namespace std;//深拷贝和浅拷贝class Person{public: //无参,默认构造函数 Person() { cout << "Person无参构造函数" << endl; } //如果使用编译器提供的默认拷贝构造函数,会进原创 2021-03-15 12:47:53 · 181 阅读 · 0 评论