C++新标准库学习笔记

移动构造

1.解决临时对象问题
2.被拷贝对象立即释放,避免一个堆内存多个引用
class A
{

}
A getTemp()
{return A(); )
int main(){
A && a = getTemp();//会调用两次移动构造
}
3.自己实现移动构造时,默认拷贝被删除。自己实现拷贝构造,默认移动构造会被删除
4.A func(){
return A();}// 首先构造一个A,然后调用拷贝构造或者移动构造
A a = func();// 再调用一次拷贝构造或者移动构造
而如果是A &&a = func();则只会传递右值引用,而不会调用任何构造

std::move

使用方法
moveable m();
moveable n(std:move(m));
1.并不执行移动操作,只是将左值转换成右值
2.类的初始化过程:父类->成员类对象->本类
3.解决了成员类对象的移动问题
移动构造里面对成员类对象使用std::move(m_xx)

enum class

传统的enum写法会带来名称重复的问题,因此新标准提出了enum class ,通过类似于命名空间的用法来避免重复
enum class season{
spring,summer,autum,winter
};
不仅如此,还可以指定枚举类型的存储类型,避免空间的浪费。
enum class season:char{
spring,summer,autum,winter
};// 指定枚举类型
这一点和结构体定义中指定位数的写法类似
struct s
{
short a:4;//表示占四个比特位
short b:6;//表示占六个比特位
short c:8;
};

编译时断言

// 编译时断言
static_assert(sizeof(void*)) !=4, “64bit not supported”);
为真时,编译报错并打印右边字符串内容
这一点和#error的用法类似,例如下面MFC DLL定义的编译时报错
#ifdef _DLL
#ifndef _AFXDLL
#error Bu

仿函数概念

传递的是对象,函数内部调用该对象的operater()

lambda表达式

1.相当于一个仿函数,是一个对象,这个对象有一个operater()
2.捕获列表为=时,将会捕获外部变量的副本,是const类型,因此如需在内部暂时修改,需要加上mutable修饰
lambda表达式添加捕获列表后不能转成函数的问题,研究了一下,特此记录一下

lambda表达式为什么添加捕获列表后就不能转成函数指针
1.为什么不添加能转
返回operate()
2.添加了不能转
调用的是lambda表达式的构造函数,构造函数没有返回值

右值引用

右值概念:1.字面值常量 2.临时对象,将亡值
作用:减少临时变量到返回值的拷贝过程
A&& a = getObject();
注意:不能反回栈对象的引用

右值构造函数

5.通过讲师介绍不能返回栈对象引用,顺便扩展了函数返回右值引用的概念,发现函数返回右值引用会编译失败,原因如下
X&& foo ()
{
X x;

return x; // ERROR: returns reference to nonexisting object
}
An rvalue reference is a reference, and returning it while referring to a local object means that you return a reference to an object that doesn’t exist any more. Whether std::move() is used doesn’t matter.
即,右值引用也属于一种引用,返回一个栈对象的右值引用意味着将会返回一个不存在对象的引用

enable_shared_from_this

关于enable_shared_from_this类的用法,以及原因,在官方文档上找了个例子,然后深入剖析了一下
struct Good : std::enable_shared_from_this // note: public inheritance
{
std::shared_ptr getptr() {
return shared_from_this();
}
};
struct Bad
{
std::shared_ptr getptr() {
return std::shared_ptr(this);
}
~Bad() { std::cout << “Bad::~Bad() called\n”; }
};
int main()
{
// ①正常 打印出引用计数为2
std::shared_ptr gp1 = std::make_shared();
std::shared_ptr gp2 = gp1->getptr();
std::cout << "gp2.use_count() = " << gp2.use_count() << ‘\n’;
try {
// ②异常 weak_ptr
Good not_so_good;
std::shared_ptr gp1 = not_so_good.getptr();
}
catch (std::bad_weak_ptr & e) {
std::cout << e.what() << ‘\n’;
}
// ③两次析构,内存访问冲突
std::shared_ptr bp1 = std::make_shared();
std::shared_ptr bp2 = bp1->getptr();
std::cout << "bp2.use_count() = " << bp2.use_count() << ‘\n’;
}
①和③可以理解,那为什么②会抛异常呢?
这要从enable_shared_from_this这个类说起,这个类的核心在于其内部维护了一个weak_ptr,通过weak_ptr可以把没有关系的shared_ptr联系起来,增加引用计数。但是,weak_ptr的初始化操作在std::make_shared函数里面完成,并不是在enable_shared_from_this类的构造中完成,所以凡是没调用std::make_shared的对象,均会因为weak_ptr没初始化导致异常

weak_ptr初始化过程位于memory文件ln1270

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值