八股文(五)

左值和右值概念的区别

1.左值一般是等号左边相对应的右值就是等号右边。左值一般那几个固定类型的,比如int、float等等具有持久的状态,右值一般是临时创建的比如函数的返回值int func(),等等一般都是临时创建的。

2.右值引用,&&只接收右值,不接受左值,左值也只接收左值除非加了个const

3.左值可以通过添加move函数将左值变化成右值引用

4(以下都是记的东西)右值引用是为了支持移动操作而引出的一个概念,它只能绑定到一个将要销毁的对象,使用右值引用的移动操作可以避免无谓的拷贝,提高性能。

----------

拷贝构造函数

拷贝构造函数的意思就是直接把别人已经构造好的类,直接拷贝拿过来复制一份。程序提供默认的拷贝构造函数,自己写也行。

class A {
 public:
	 int a=3;
	 double c=4.0;
};
int main() {
	A L;
	A c(L);
	cout << c.a << c.c;
}

有的时候之所以要自定义拷贝构造函数是因为,有时候初始化了指针,在拷贝的时候会将指针直接拷贝过去,就可能出现同一块内存重复析构的问题。

当然这也是深浅拷贝的问题,浅拷贝是直接把指针复制过去,指向同块内存空间,深拷贝会另外创造一个一模一样的对象,指向一块新的内存空间。

移动构造函数(这个也还没掌握)

移动构造函数需要传递的参数是一个右值引用,移动构造函数不分配新内存,而是接管传递而来对象的内存,并在移动之后把源对象销毁;移动拷贝构造函数需要传递一个左值引用,可能会造成重新分配内存,性能更低。

-----

内联函数

内联函数优点是能节省了程序的开销,缺点是内联函数里面放的代码量尽量少。写法也简单,在函数前面加个inline就行了。

宏函数优点像C++的模板,优点相对于函数更高效,因为不需要栈的开销,缺点是没有类型检测,(不同的参数就需要不同的函数)导致源文件变长,没有返回值。在传入参数的时候,不使用括号保护参数,可能会出现错误。

#include<iostream>
using namespace std;
#define a(x,y)(x*y)// 这边下x,y如果没用括号括起来可能会出现问题
int main(){
	int m;
	m = a(3+1, 7+2);
	cout << m;
}

宏有几个#代表传入几个参数,如果宏可以接收两个参数,但是只传入一个参数的话,宏还是会默认补充上为传入的(比如下面这个test2,下面输入test2(abc)则实际传入的变成了abcb,最后这个b会默认补上)

#include<iostream>
using namespace std;
#define test1(a)#a
#define test2(a)a##b
#define test3(a,b)a##b
#define abcabc 10

int main() {
	int a = 3;
	int b = 2;
	cout << test3(abc,abc);
}

宏和inline的区别(直接背就行)

(1)define宏命令是在预处理阶段对命令进行替换,inline是在编译阶段在函数调用点处直接展开函数,节省了函数调用的开销;

(2)define的话是不会对参数的类型进行检查的,因此会出现类型安全的问题,比如定义一个max命令,但是传递的时候可能会传递一个整数和一个字符串,就会出错,但是内联函数在编译阶段会进行类型检查;

(3)使用宏的时候可能要添加很多括号,比较容易出错。

------

lambda

可以理解成匿名的内联函数。

lambda的格式为

[ capture ] ( params ) opt -> ret { body; };

其中 capture 是捕获列表,params 是参数表,opt 是函数选项,ret 是返回值类型,body是函数体。

捕获列表有这几种的写法

  • [] 不捕获任何变量。
  • [&] 捕获外部作用域中所有变量,并作为引用在函数体中使用(按引用捕获)。
  • [=] 捕获外部作用域中所有变量,并作为副本在函数体中使用(按值捕获)。
  • [=,&foo] 按值捕获外部作用域中所有变量,并按引用捕获 foo 变量。
  • [bar] 按值捕获 bar 变量,同时不捕获其他变量。

还有一些其他的作用可以看这篇文章C++11 lambda表达式精讲 (biancheng.net)

--------

引用和指针的区别

1.引用本质上是变量本身,指针是一个常量指向另一个常量,本质是一个地址

2.指针可以有多级,int**p,引用只有一级

3.指针初始化后还可以指向其他对象,引用初始化后只能固定指向一个对象;指针初始化可以指向nullptr,引用一开始就得有初始值,对已有对象的引用

-------------------

重载、重写、隐藏

函数重载是函数参数列表,函数返回值不同的情况下,根据传入不同的参数,返回值调用不同的函数。

重写,在继承的时候,对基类虚函数进行虚继承的时候进行的重写操作,要想调用派生类函数,跟上面重载不同的是,需要创建一个父类指针指向子类的空间,然后在调用

吟唱

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值