
C/C++
文章平均质量分 79
不摆烂的zzz
这个作者很懒,什么都没留下…
展开
-
类与对象的构造,析构和内存管理
对象的构造过程创建一个对象分为两个步骤1.首先取得对象所需的内存(从线程栈或全局堆)2.然后在内存空间上执行构造函数在构造函数构建对象时,构造函数也分为两个步骤1.执行初始化(通过初始化参数列表)2.执行构造函数的函数体class Derived : public Base{public: Derived(): id(1), name("UnNamed") // 1 { // do something // 2 }private:原创 2021-11-05 08:59:10 · 486 阅读 · 0 评论 -
友元的作用以及使用场景
作用友元提供了不同类的成员函数之间,类的成员函数与一般函数之间数据共享机制,通过友元,一个不同函数或另一个类中的成员函数可以访问类中的私有成员和保护成员使用场景1.普通函数定义为友元函数,使普通函数能够访问类的私有成员class A{ friend ostream &operator<<(ostream &_cout, const A &tmp); // 声明为类的友元函数public: A(int tmp) : var(tmp) {原创 2021-11-04 16:03:45 · 2585 阅读 · 0 评论 -
虚函数详解
虚函数表相关知识点:1.虚函数表存放的内容:类的虚函数的地址2.虚函数表建立的时间:编译阶段,即程序的编译过程中会将虚函数的地址放在虚函数表中3.虚表指针保存的位置:虚表指针存放在对象的内存空间中最前面的位置,这是为了保证正确取到虚函数的偏移量注:虚函数表和类绑定,虚表指针和对象绑定,即类的不同的对象的虚函数表是一样的,但是每个对象都有自己的虚表指针。在编译时,一个类的虚函数表就确定了,这也是为什么它放在了只读数据段中1.编译器将虚函数表的指针放在类的实例对象的内存空间中,该对象调用类的虚函数时,原创 2021-11-04 14:15:14 · 9356 阅读 · 2 评论 -
内存对齐问题
结构体大小与数组不一样的是,结构体大小不是所有成员大小的简单相加,需要考虑系统在存储结构体变量时的地址对齐问题struct stu1{ int i; char c; int j; }用sizeof求该结构体大小,发现值为12,int占4字节,char占1字节,应该是9字节才对,为什么呢先介绍一个相关的概念–偏移量,偏移量指的是结构体变量中成员的地址和结构体变量地址的差,结构体大小等于左后一个成员的偏移量加上最后一个成员的大小,显然,结构体变量中的第一个成员的地址就是结构体变量的首地址,因此原创 2021-11-02 14:34:50 · 326 阅读 · 0 评论 -
C++指针
## 野指针概念:野指针就是指向一个已删除对象或者未申请访问受限内存区域的指针产生原因:1.指针定义时未被初始化:指针在被定义的时候,如果程序不对其初始化的话,它会随机指向一个区域,因为任意指针数量(除了static修饰的指针)它的默认值都是随机的。2.指针被释放时没有置空:我们在用malloc()开辟空间的时候,要检查返回值是否没空,如果为空,则开辟失败。指针指向的内存空间在用free()和delete释放后,如果程序员没有对其进行置空或者其他赋值操作的话,就会成为一个野指针。3.指针操作超越原创 2021-11-02 09:53:44 · 680 阅读 · 0 评论 -
C++11新特性
C++11新特性1.auto & decltypeauto:让编译器在编译期就推导出变量的类型,可以通过=右边的类型推导出变量的类型auto a = 10 //10是int类型自动被推导出来decltype:相对于auto用于推导类型变量,而decltype则用于推导表达式类型,这里只用于编译器分析表达式类型,表达式实际不会进行运算const int& i = 1;decltype(i) b = 2; //b是const int&2.nullptrnullptr是原创 2021-11-01 19:14:25 · 453 阅读 · 0 评论 -
inline关键字
作用inline是一个关键字,可以用于定义内联函数,像普通函数一样被调用,但是在调用时并不通过函数的调用机制,而是直接在调用点展开,这项可以大大减少由函数调用带来的开销,从而提高程序的运行效率特征相当于把内联函数里面的内容写在调用内联函数处相当于不用执行进入函数的步骤,直接执行函数体相当于宏,却比宏多了类型检查,真正具有函数特性编译器一般不内联包括循环,递归,switch等复杂操作的内联函数在类声明中定义的函数,除了虚函数的其他函数都会自动隐式地当内联函数编译器对inline函数的处理步骤原创 2021-10-29 17:30:23 · 2007 阅读 · 1 评论 -
static关键字
static全局变量和普通全局变量相同点:存储方式:普通全局变量和static全局变量都是静态存储方式不同点:作用域:普通全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,普通全局变量在各个源文件中都是有效的;静态全局变量则是限制了其作用域,在同一源程序的其他源文件中不能使用它,由于静态全局变量的作用域限于一个源文件,只能为该源文件内函数公用,因此可以避免其他源文件中引起错误初始化:1.修饰普通变量,修改变量的存储区域和生命周期,使变量存储在静态区,在main函数运行前就分配了空间,原创 2021-10-29 16:16:45 · 99 阅读 · 0 评论 -
程序编译流程
程序编译流程程序编译流程分为预处理,编译,汇编,链接一丶预处理1.预处理阶段会将所有#define删除,并展开所有的宏定义2.处理所有的条件编译指令,如#if,#ifdef,这些伪指令的引入使得程序员可以通过定义不同的宏来决定编译程序对哪些代码进行处理,预编译程序将根据有关文件,将不必要的代码过滤掉3.处理#include预编译指令,将被包含的文件插入到该预编译指令的位置(递归进行的,被包含的文件可能还包含其他文件)4.删除所有注释5.添加行号和标识,以便于编译器产生调试用的行号信息及用于编译原创 2021-10-20 07:08:54 · 1138 阅读 · 0 评论 -
C++内存
内存一丶内存分配方式C++中内存分为五个区,分别是栈(stack),堆(heap),自由存储区,全局/静态存储区(bss),常量存储区栈:在执行函数时,函数内局部变量的存储单元,函数参数都可以在栈上创建,函数执行结束时这些存储单元自动被释放,栈内存分配运算内置于处理器指令集中,效率高,但分配内存容量有限。堆:那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete,如果程序员没有释放掉,程序结束后,操作系统会自动回收(内存泄漏不是系统无法回收那原创 2021-09-26 16:39:54 · 747 阅读 · 0 评论 -
深入探索C++对象模型读书笔记(二)
第二章:构造函数语义学2.1 必要的默认构造函数(nontrivial default constructor)的四种情况1.带有default constructor的成员对象(member class object)2.带有default constructor的基类(base class)3.带有一个虚函数(virtual function)的类4.带有一个虚基类(virtual base class)的类在合成的default constructor中,只有基类子对象(base clas原创 2021-09-24 10:18:29 · 127 阅读 · 0 评论 -
深入探索C++对象模型读书笔记(一)
第一章:对象1.C++对象模型在C++中,有两种class data members:static和nonstatic以及三种class member functions:static,nonstatic和virtual已知下面这个class Point声明class Point {public: Point(float xval ); virtual ~Point(); float x() const; static int PointCount();protected: virt原创 2021-09-22 21:47:27 · 134 阅读 · 0 评论 -
C++完美转发
完美转发一丶万能引用与引用折叠template<typename T>void func(T&& value){}int i = 1;int &&k = i;func(i);func(1);fuuncfunc(k);func中的形参其实是一个万能引用,当实参为左值时,T和func(i) :实参为左值,故此时T将被推断为int&,value则为int&...原创 2021-09-20 10:27:40 · 1139 阅读 · 0 评论 -
左值与右值
左值与右值一、左值左值表示一个占据内存中可识别位置的一个对象,更进一步地,可以对左值取地址int a = 10;int *p = &a;int **q = &p;a,p,q都是很经典的左值,可以通过标识符a,p,q,取出内存地址中对应的对象int a;// ①a = 4;// ②①如果在函数中执行该语句的话,变量a会在栈帧中开辟一个4字节的内存空间其值未定义。所以a为左值,能够取其地址②赋值语句中左操作数必须是一个左值,赋值操作本质上是对内存进行更新,所以我们必须要找原创 2021-09-18 14:10:23 · 5508 阅读 · 5 评论 -
Template
Template一丶函数模板与类模板函数模板和类模板本质上可以理解成泛型函数和泛型类,但是它们实际上是模板,而不是真正的函数和类,添加template<typename 类型1,typename类型2,…>并替换掉原有硬编码类型的声明即可函数模板:template<typename T>const T& maxOfThree(const T& a, const T& b, const T& c) { const T& maxV原创 2021-09-18 10:20:30 · 163 阅读 · 0 评论 -
强制类型转换
强制类型转换一、C风格的强制类型转换在C语言中,强制类型转换是通过“(目标类型)变量名”或者“目标类型(变量名)所实现的”,例如(int)3.14或者int(3.14),前者的方式常称之为C风格的类型转换,后者则被称之为函数风格的强制类型转换二、static_caststatic_cast<目标类型>(expression)static即为静态类型转换,在编译时进行类型检查以及类型转换,但没有运行时类型检查来保障安全性,其作用主要有4个1.相关类型间的转换,double->i原创 2021-09-17 10:43:27 · 1059 阅读 · 0 评论 -
堆,栈和RALL:C++管理资源的方式
堆,栈和RALL:C++管理资源的方式一、堆(heap)1.由程序员动态分配,底层由malloc和free进行管理2.同样的使用new关键字也在堆上分配内存,但并不是每一次new都会调用底层的malloc方法,因为有这内存池的存在3.在函数中如果非必需,不然不要使用堆内存void buzz() {vector<int> *p = new vector<int>(100);...... delete p;}上述代码这么写是有问题的,如果在…函数操作的时候代码抛出原创 2021-09-15 15:28:15 · 564 阅读 · 0 评论 -
const关键字
const关键字一、作用1.const为修饰符,用于修饰对象或者变量,表示其不可被修改2.定义常量,const时最为直接的使用方式,比如定义PI3.防止变量被修改,在函数声明中指出不可被修改的参数,可防⽌实参(引⽤ or 指针指向的对象)被修改,降低出现 BUG 的概率,函数返回值同理二丶多文件编程中的使用const所修饰的对象默认为当前文件的局部变量,因此如果需要在多个文件中使用定义的const需要显式的声明externextern const double PI = 3.14; //定义原创 2021-09-15 13:13:22 · 111 阅读 · 0 评论 -
C++类的缺省函数
1.构造函数2.拷贝构造函数3.赋值函数4.析构函数5.取址运算符6.取址运算符const#include<iostream>using namespace std;class Test{public: Test(int data=0):m_data(data) { cout<<"create Test object:"<<this&...原创 2019-07-19 19:32:30 · 502 阅读 · 0 评论 -
字节对齐
字节对齐#pragma pack(4)typedef struct Test{ short a;//2+2 struct t { int b;//4 double c;//8 char d;//1+3 }tt; long e;//4}TEST;void main(){ cout<<sizeof(Test)<<endl;//24}...原创 2019-07-31 22:32:21 · 107 阅读 · 0 评论 -
C++面向对象三大特性
1.封装封装是把对象的全部属性和行为结合成一个独立的单位,并尽可能隐蔽对象内部的细节,降低了系统的复杂性,提供了代码的重用性2.继承它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。继承的目的是为了实现多态3.多态允许将子类类型的指针赋值给父类类型的指针,一个接口,多种实现静态编译时的多态性,编译时的多态性是通过重载来实现的动态运行时的多态性,运行时的多...原创 2019-08-15 23:15:32 · 1068 阅读 · 0 评论 -
malloc和new区别
1.new/delete是C++关键字,需要编译器支持,malloc/free属于库函数,需要头文件支持2.使用new操作符申请内存分配时,无需指定内存块大小,Malloc需显示指出内存尺寸3.成功时返回对象类型指针, 返回void*通过强转成我们需要的类型4.失败时抛出异常, 返回NULL5.new在分配对象内存时首先会调用operator new来分配一块足够大,原始的,未...原创 2019-08-31 08:27:19 · 112 阅读 · 0 评论 -
sizeof和strlen区别
sizeof和strlen区别strlen是一个函数,作用是计算长度,到’\0’为止sizeof是一个运算符,作用是计算大小void main(){ char str[]="hello"; cout<<strlen(str)<<endl;//5 cout<<sizeof(str)<<endl;//6}当不给定数组大小初始化字...原创 2019-07-18 21:09:13 · 132 阅读 · 0 评论