
C++学习笔记
C++学习笔记
CET4_
这个作者很懒,什么都没留下…
展开
-
C++ mutex
读写锁 shared_mutex若一个线程已获取独占性锁(通常不直接调用 lock() ,用 std::unique_lock 与 std::lock_guard 管理排他性锁定 ),则无其他线程能获取该锁(包括共享的)。仅当任何线程均未获取独占性锁时,共享锁能被多个线程获取(通过 std::shared_lock )。在一个线程内,同一时刻只能获取一个锁(共享或独占性)。mutable std::shared_mutex mutex_;unsigned int value_ = 0;// 多原创 2022-04-07 17:03:01 · 391 阅读 · 0 评论 -
C++ static关键字
**静态数据成员**类中数据成员的声明前加上static为该类的静态成员。类的静态数据成员在类实现文件中初始化,否则会出现未定义错误,且初始化时无需再用static关键字修饰,无论类被实例化多少个,静态数据成员都只有一份拷贝,为该类型的所有对象所共享。**//单例模式实现template<typename T>class singleton{ public: template <typename... Args> static T* Ins原创 2022-04-02 17:41:41 · 1058 阅读 · 0 评论 -
C++一些内置宏
FILE :正在编译文件的文件名LINE :正在编译文件的行号DATE:编译时刻的日期字符串TIME:编译时刻的时间字符串STDC:当要求程序严格遵循ANSI C标准时该标识被赋值为1__cplusplus:当编写C++程序时该标识符被定义...原创 2021-10-12 15:39:46 · 348 阅读 · 0 评论 -
(C++)前置声明
前置声明在类的互包含中用到,还可以减少头文件的包含层次。像我们这样前置声明类A:class A;是一种不完整的声明,只要类B中没有执行需要了解类A的大小或者成员的操作,则这样的不完整声明允许声明指向A的指针和引用。而A a;是需要了解A的大小的,不然是不可能知道如果给类B分配内存大小的,因此不完整的前置声明就不行,必须要包含a.h来获得类A的大小,同时也要重新编译类B。再回到前面的问题,使用前置声明只允许的声明是指针或引用的一个原因是只要这个声明没有执行需要了解类A的大小或者成员的操作就可转载 2021-09-22 14:50:51 · 854 阅读 · 0 评论 -
(C++)纯虚函数
纯虚函数是在声明虚函数时被“初始化”为0的函数声明纯虚函数的一般形式:virtual 函数类型 函数名 (参数表列) = 0;纯虚函数没有函数体;最后面的“=0”并不表示函数返回值为0,它只起形式上的作用,告诉编译系统“这是纯虚函数”;这是一个声明语句,最后应有分号。纯虚函数只有函数的名字而不具备函数的功能,不能被调用。它只是通知编译系统: “在这里声明一个虚函数,留待派生类中定义”。在派生类中对此函数提供定义后,它才能具备函数的功能,可被调用。原文...原创 2021-09-07 11:55:51 · 292 阅读 · 0 评论 -
(C++) 头文件使用““与<>的区别
用 #include <filename.h> 格式来引用标准库的头文件(编译器将从标准库目录开始搜索)用 #include “filename.h” 格式来引用非标准库的头文件(编译器将从用户的工作目录开始搜索)原创 2021-08-06 15:15:08 · 295 阅读 · 0 评论 -
(C++) 条件编译
使用几个指令来有选择地对部分程序源代码进行编译,这个过程被称为条件编译。用法:1.#(ifdef + 标识符) … #else … #endif#ifdef (标识符) //可以理解为# if define 程序段1 //当标识符被定义过,编译程序段1 #else 程序段2 //否则编译程序段2 #endif 2.#(ifndef + 标识符) … #else … #endif#ifndef (标识符) //可以理解为# if not defin原创 2021-08-05 15:54:03 · 287 阅读 · 0 评论 -
C++ typedef 函数指针用法
作用:代码简化, 促进跨平台开发的目的。与#define区别:typedef 行为有点像 #define 宏,用其实际类型替代同义字。typedef 在编译时被解释,因此让编译器来应付超越预处理器能力的文本替换。示例:typedef int (*Myfunc)(char, char); //这种用法一般用在给函数定义别名的时候//上面的例子定义Myfunc 是一个函数指针, 函数类型是带两个char 参数, 返回类型为int //在分析这种形式的定义的时候可以用下面的方法: //先原创 2021-08-03 20:52:06 · 340 阅读 · 0 评论 -
内存泄漏及危害
内存泄漏内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。危害长期运行的程序出现内存泄漏,影响很大,如操作系统、后台服务等等,出现内存泄漏会导致响应越来越慢,最终卡死。内存泄漏分类C/C++程序中一般我们关心两种方面的内存泄漏:堆内存泄漏(Heap leak)堆内存指的是程序执行中依据须要分配通过malloc / calloc / realloc /原创 2020-11-25 20:51:32 · 2484 阅读 · 0 评论 -
悬空指针与野指针
悬空指针一个指针的指向对象已被删除,那么就成了悬空指针。野指针指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)指针变量在定义时如果未初始化,其值是随机的,指针变量的值是别的变量的地址,意味着指针指向了一个地址是不确定的变量,此时去解引用就是去访问了一个不确定的地址,所以结果是不可知的。...原创 2020-11-25 20:45:18 · 162 阅读 · 0 评论 -
(C++)4种强制类型转换
标准C++为了加强类型转换的可视性,引入了四种命名的强制类型转换操作符:static_castconst_castdynamic_castreinterpret_caststatic_caststatic_cast用于非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可用static_cast,但它不能用于两个不相关的类型进行转换 void test() { double d = 12.34; int a = static_cast<int>(d); co原创 2020-10-18 14:42:44 · 242 阅读 · 0 评论 -
(C++)构造函数和析构函数中的虚函数
原文引自《C++ Prime》中文版P497:构造派生类对象时首先运行基类构造函数初始化对象的基类部分。在执行基类构造函数是,对象的派生类部分是未初始化的。实际上,此时对象还不是一个派生类对象。撤销派生类对象时,首先撤销它的派生类部分,然后按照与构造顺序的逆序撤销它的基类部分。在这两种情况下,运行构造函数或析构函数的时候,对象都是不完整的。为了适应这种不完整,编译器将对象的类型视为在构造或析构期间发生了变化。在基类构造函数或析构函数中,将派生类对象当作基类类型对象对待。示例: class A原创 2020-10-16 21:31:30 · 267 阅读 · 0 评论 -
单例模式
单例模式单例模式是一种常用的软件设计模式,其定义是单例对象的类只能允许一个实例存在。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。优点:在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。避免对资源的多重占用(比如写文件操作)。缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。原创 2020-10-11 22:59:47 · 112 阅读 · 0 评论 -
程序内存分区中的栈与堆
栈栈由操作系统自动分配释放 ,用于存放函数的参数值、局部变量等,其操作方式类似于数据结构中的栈。参考如下代码:int main(){ int b; //栈 char s[] = "abc"; //栈 char *p2; //栈}其中函数中定义的局部变量按照先后定义的顺序依次压入栈中,也就是说相邻变量的地址之间不会存在其它变量。栈的内存地址生长方向与堆相反,由高到底,所以后定义的变量地址低于先定义的变量,比如上面代码中变量 s 的地址小于变量 b 的地址,p2 地址小于 s 的原创 2020-10-10 20:45:40 · 230 阅读 · 0 评论 -
C++常对象和常成员函数
常对象常对象是指该对象在其生命周期内,其所有的数据成员的值都不能被改变;定义对象时加上关键字const,该对象就是常对象,其一般形式如下:类名 const 对象名[(实参类别)];或者const 类名 对象名[(实参类别)];形如:const CComplex num;需要特别说明的是:常对象只能调用常成员函数,不能调用普通成员函数 (除了隐式调用析构函数和构造函数),常成员函数是常对象的唯一对外接口;现在编译系统只检查函数的声明,只要发现调用了常对象的成员函数,而且该函数未被声明为c原创 2020-10-10 15:22:12 · 270 阅读 · 0 评论 -
C++11学习总结
新增基于范围的for循环类似Java中foreach语句,为遍历数组提供了很大方便。int nArr[5] = {1,2,3,4,5};for(int &x : nArr){ x *=2; //数组中每个元素倍乘}自动类型推断 auto编译器可以根据初始值自动推导出类型,但是不能用于函数传参以及数组类型的推导。无需提前声明定义的变量的数据类型。例如:auto i = 1; //编译器自动推断i为int类型这个功能在各种标准模板库容器中使用,作用更突出。如下:原创 2020-09-09 16:14:45 · 239 阅读 · 0 评论 -
C和C++内存模型
C分为四个区:堆,栈,静态全局变量区,常量区C++内存分为5个区域(堆栈全常代 ):堆 heap :由new分配的内存块,其释放编译器不去管,由我们程序自己控制(一个new对应一个delete)。如果程序员没有释放掉,在程序结束时OS会自动回收。涉及的问题:“缓冲区溢出”、“内存泄露”栈 stack :是那些编译器在需要时分配,在不需要时自动清除的存储区。存放局部变量、函数参数。存放在栈中的数据只在当前函数及下一层函数中有效,一旦函数返回了,这些数据也就自动释放了。全局/静态存储区 (.bss转载 2020-09-07 14:24:33 · 202 阅读 · 0 评论 -
static,virtual在一个类中的内存分布
1、static修饰符1)static修饰成员变量对于非静态数据成员,每个类对象都有自己的拷贝。而静态数据成员被当做是类的成员,无论这个类被定义了多少个,静态数据成员都只有一份拷贝,为该类型的所有对象所共享(包括其派生类)。所以,静态数据成员的值对每个对象都是一样的,它的值可以更新。因为静态数据成员在全局数据区分配内存,属于本类的所有对象共享,所以它不属于特定的类对象,在没有产生类对象前就可以使用。2)static修饰成员函数与普通的成员函数相比,静态成员函数由于不是与任何的对象相联系,因此它不具原创 2020-09-07 12:45:24 · 402 阅读 · 0 评论