内联
在频繁调用一个函数时,会建立栈帧,如何减少内存的消耗
int add(int x,int y)
{ return (x+y)*10; }
c语言中,用宏函数 #define add(x,y) (((x)+(y))*10)
若不加括号会出现一些问题
宏优势 不需要建立栈帧,提高调用效率,可复用和修改
缺点 易出错 复杂 可读性差 不能调试
由于宏太容易出错了,于是有了内联函数 inline
内联函数 不需要建立栈帧 不复杂 不容易出错 可以调试 适用于短小的 频繁调用的函数 太长了容易代码膨胀 会让安装包变大
inline对于编译器仅仅只是一个建议,是否变为内联由编译器自己决定
不会变成内联的情况:
1.较长的函数 2.递归函数
eg:Func(); 如果代码中有1000个位置调用Func(),那么
默认debug版本下inline不会起作用,否则无法调试 而release不方便汇编
需要调一下编译器 在设置里边 常规-调试信息格式-程序数据库
c/c++ 优化-内联函数扩展-只适用于inline
让它不是内联 多输出一些cout
内联声明和定义不分离
nullptr 优化
用空指针就用nullptr 语言建立的原则是向前兼容
C语言是面向过程的,C++是面向结果的,C++更关注对象与对象之间的关系和交互
C++兼容C语言,struct之前的用法都可以用, 类也升级成为了类。并且在struct类里边可以写成员函数
struct类也可以用访问限定符
struct不写访问限定符默认是公有,class默认是私有(唯一区别)
封装
面向过程 C语言 关注过程步骤 面向对象 C++ 关注点是对象与对象之间的关系和交互,将现实世界中的类和对象映射到虚拟计算机系统中
本质是为了更好地管理,让用户方便使用类
类里面定义的函数默认是内联(inline),所以一般函数体中内容较短的直接在类内定义,较长的就在类外定义。
class Data
{
public:
void Init(int year)
{//局部域
year=year;
//这句代码表示的是将局部域的year赋值给类域的year,
//等号右边表示局部域的year,左边表示类域的year
//遵循局部优先原则
//域:类域 局部域 全局域 命名空间域
默认访问顺序:局部域-->全局域-->展开了的命名空间域or指定访问命名空间域
}
private:
int year;//类域
int month;
int day;
};
声明和定义的真正区别在于开不开空间 声明类似于图纸,只有实例化之后才能才能赋值(存放数据),类型可以实例化出很多对象
计算类的大小
只算成员变量的大小(需要类型对齐),不算成员函数,成员函数相当于小区里边的篮球场,建在小区里边,属于公共区域。成员函数如果每个对象里头都有的话会造成很大的浪费。成员函数在公共代码区域里边存储,编译的时候去公共区域找寻,而不是到对象里边找。
//计算大小
class A
{
public:
void Print()//成员函数不计算在大小里面
{
}
private:
char _a;//大小是1
...
};
int main()
{
A aa;
sizeof(A);//sizeof(类)
sizeof(aa);//sizeof(对象名)
//这两种方式都是可行的
//相当于直接通过图纸来计算房子面积/拿尺子来计算房子面积
return 0;
}
空类的大小是1,一字节是为了占位。如果是0,没有地址
ps:结构体对齐
为什么要进行内存对齐?
硬盘决定一次读取多少位(可能是4位),如果不进行内存对齐可能存在一个数据要读取多次
this指针
是一个const类型的指针,不能在形参和实参中显式传递,但是函数内部可以使用。
eg:Data* const this
//在* 之后修饰this本身,this不能改,但this指向内容可以改
:: 域作用访问限定符 前边可以是类域/命名空间域
this指针是形参 实参传给形参得建立栈帧,跟普通函数一样得进行压栈,存在栈区里边