前言
今天主要讲引用与指针,宏与内敛函数,auto与范围for,与类和对象的相关知识。
一、引用与指针
1.相同点
int& ref = Count();
int a = 0;
int* p1 = &a;
int& ref = a;
++(*p1);
++ref;
引用和指针底层逻辑是一样的,汇编代码都一样
底层只有指针,没有引用
引用不过是化了妆的指针罢了
2.区别
二、宏与内敛函数
1.宏
宏有宏参数和宏函数之分
宏是一种替换,
宏后面不能给分号
//宏参数
#define N 10
// 实现一个ADD的宏函数
#define ADD(x, y) ((x)+(y))
1.宏的优点
1.没有类型的严格限制
2.针对频繁调用的小函数,不需要再不建立栈帧,提高了效率
2.宏的缺点
1.容易出错,语法坑很多
比如上面的ADD函数,就可能出现下面的各种写法
// #define ADD(int x, int y) {return x+y;}
// #define ADD(x, y) (return x+y;)
// #define ADD(x, y) return x+y;
//#define ADD(x, y) x+y;
//#define ADD(x, y) x+y
//#define ADD(x, y) (x+y)
#define ADD(x, y) ((x)+(y))
2.不能调试
因为在预处理时宏就被替换了
3.没有类型的安全检查
2.内敛函数
1.特点
内敛函数用来代替宏函数
内敛函数不建立栈帧,直接展开,适用于短小,调用次数多的函数
2.注意事项
值得注意的是,内敛函数太长,会导致代码膨胀
因为内敛函数会直接展开,会增加代码长度,所以内敛只是自己向编译器提出的一个申请,编译器还会检查一下是否合适,合适才会整成内敛
内敛函数声明和定义不能分开,会出现链接错误,因为它直接展开,不生成指令,不建立栈帧,符号表里没有它的地址,使用时找不到
三、auto与范围for
1.auto
auto在定义时会根据右边类型自动匹配类型
int a = 0;
//int b = a;
auto b = a;
auto c = &a;
auto& d = a;
// 普通场景没有什么价值
// 类型很长,就有价值,简化代码
std::vector<std::string> v;
//std::vector<std::string>::iterator it = v.begin();
auto it = v.begin();
要注意的是,auto不能用来定义数组
函数定义时不能作为形参参数
2.范围for
// 范围for
// 依次取数组中的数据赋值给e
// 自定判断结束
// 自动迭代
for (auto e : array)
{
cout << e << " ";
}
里面的auto是可以改成数组数组中元素的类型,但是auto更方便
值得注意的是,取数组中的元素赋值给e,改变e不影响数组中的元素
如果要改变数组中的元素的话,只需要改成引用就好
for (auto& x : array)
{
x *= 2;
}
四、NULL与nullptr
先看这样一段代码
都会匹配到第一个
因为NULL实际是一个宏,在c++中,把NULL定义成了0,而不是((void*)0)
于是在c++中用nullptr来代替NULL
1.在使用nullptr表示指针空值时,不需要包含头文件,因为nullptr是C++11作为新关键字引入的。
2. 在C++11中,sizeof(nullptr) 与 sizeof((void*)0)所占的字节数相同。
3. 为了提高代码的健壮性,在后续表示指针空值时建议最好使用nullptr。
五、struct与class
1.struct
我们在c语言中定义结构体使用的是struct,而在c++中,结构体升级成了类,但是仍然兼容c语言的语法,我们依然可以用它来定义类
与c语言不同的是,类可以直接作为类型名定义对象,但是之前的方法依然适用
struct Stack st1;
Stack st2;
而且类中不仅可以定义成员变量,还可以定义成员函数,类中的成员函数不用再传类中已有的参数,直接用
其默认权限是public
2.class
class是c++中另一个定义类的关键字,其与struct主要区别是,class默认为私有
3.访问限定符
c++为实现封装,使用访问限定符,访问限定符有public,protected,private
4.struct与class区别
六、类的定义
//.h中放函数声明
class Stack
{
public:
void Init();
private:
int* a;
int top;
int capacity;
};
//.cpp中放定义
void Stack::Init()
{
a = nullptr;
top = capacity = 0;
}
在定义时一定要加上类域,否则不会在类中找定义,只会在全局中搜索
在全局中,函数找变量只会往上查找,但是类中的函数会在整个类中查找,无关顺序
七、命名风格
这样就会没办法区分类内的成员变量和外面传过来的,根据局部优先,赋值就会失败
所以在类中写成员变量时,一般要加一些符号来区分,但是这个如何写并没有强制要求,可以根据自身意愿来写
八、类的实例化
报错原因是只是声明了,不是定义,没有开空间,所以没办法访问成员变量
声明和定义的区别:是否开空间
由此引出了类的实例化:
类就像一张建造图纸,不造房子的话是不占地方的,只有建造了房子才占地,才能住人
同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间
九、对象的存储方式
类不占内存空间,不存在内存里
不能存数据,实例化之后才能存储
类中的函数不存在对象里面,存在公共代码区,也即代码段中
类中的函数是共用的,可以但是没必要存在类中,如果存在类中,每实例化出一个对象,都要存一次函数,这样是没必要的
总结
以上就是今天的内容,前面大部分是c++对于c语言的一些改进语法,后面是类和对象的一小部分。