(头文件,智能指针和动态内存)c++第一次复习

默认构造函数优先度

先执行构造函数初始值列表,列表中没有初始化的数据成员执行类内初始化,如果
前面两种方式都没有执行,则执行默认初始化

头文件应该包括什么

(1)类的定义。

将类定义在头文件中,友元声明也应该与相应的类定义在同一个头文件中。

(2)const变量

建议const变量定义在cpp文件中,在头文件中只包含该const变量的声明(前提是这个const变量
需要在多文件中使用)。还有一点要注意的是,定义在函数外部的const变量默认具有文件作用域。

(3)inline内联函数

将类定义在头文件中,并且类中inline成员函数也应该与类定义在同一个头文件中。
友元声明也应该与相应的类定义在同一个头文件中。

智能指针和异常

如果使用智能指针,在程序抛出异常注资后智能指针会自动释放内存,但若使用new内置指针,则若程序在new和delete之间抛出异常(即内存泄漏的定义),则该部分内存永远不会被释放;故最好使用智能指针。

同理标准库类在内的很多C++类都定义了析构函数,负责清理对象使用的资源。但是,不是所有的类都是这样良好定义的。
那些分配了资源,而又没有定义析构函数来释放这些资源的类,可能会遇到与使用动态内存相同的错误。类似的,如果在资源分配和释放之间发生了异常,程序也会发生资源泄漏。
注意:弃用auto_ptr

使用new和delete管理动态内存常见的三种错误:

1.忘记delete。这就是常说的内存泄露问题,查找内存泄露问题很困难,因为通常应用程序运行很长时间,真正耗尽内存后,才会被发现;
2.使用已经释放掉的内存。通过释放内存后将指针置为空,有时可以检测出这种情况;
3.同一块内存释放两次。当有两个指针指向相同的动态空间时可能会发生这种情况,delete第一次的时候,内存空间已经被归还了,再释放一次,自由空间就可能遭到破坏。

故使用智能指针

在这里插入图片描述
shared_ptr允许多个指针指向同一个对象;
unique_ptr则“独占”所指向的对象。

在这里插入图片描述
例:auto p=make_shared(40);(使用auto来让初始化器来推断我们想要分配的对象的类型,但是只有当括号中仅有单一初始化器时才能使用:)
shared_ptr存在引用计数,假若复制一次则进行一次计数,当给shared_ptr赋予新值或者被销毁的时候,计数器就会递减,当计数器的值减为0时,他就会自动销毁自己管理的对象,释放相关联的内存。

	unique_ptr<string> p1(new string("this is a good thing"));
	cout<<*p1<<endl;                 //输出this is a good thing
	
	unique_ptr<string> p2(p1.release());
	cout<<*p2<<endl;                //输出this is a good thing
	if(p1 == NULL){
		cout<<"p1为空"<<endl;       //执行这句
	}
	else{
		cout<<"p1不为空"<<endl;
	}
	
	unique_ptr<string> p3(new string("this is a bad thing"));
	p2.reset(p3.release());        //释放了原来的内存再指向另外的
	cout<<*p2<<endl;               // 输出this is a bad thing
	if(p3 == NULL){
		cout<<"p3为空"<<endl;      //执行这句
	}
	else{
		cout<<"p3不为空"<<endl;
	}

在这里插入图片描述
与shared_ptr不同的是,unique_ptr没有类似make_shared的函数返回指针。当我们定义一个unique_ptr时,需要将其绑定到一个new返回的指针。初始unique_ptr必须使用直接初始化形式。因为unique_ptr拥有它指向的对象,所以它没有赋值或拷贝操作
虽然不能拷贝和赋值,但是可以通过调用release和reset来将指针的所有权转交给另一个指针:值得注意的是release只是切断和对象的联系,并不释放对象的内存,需要我们手动释放:

`auto p = p1.release();
delete(p);

不能拷贝unique_ptr规则有一个例外:可以拷贝或赋值一个将要被销毁的unique_ptr,比如:

unique_ptr<int> clone(int p){
	return unique_ptr<int>(new int(p));
	//或者 
	//unique_ptr<int> r(new int(p));
	//return r;
}

`创建一个weak_ptr时,要用一个shared_ptr来初始化它。
在这里插入图片描述
auto p = make_shared(42);
weak_ptr wp§;
weak_ptr不增减引用计数
对象可能不存在,所以不能使用weak_ptr直接访问对象,需要先调用lock检查对象是否还存在。

总结

智能指针可以提供对动态内存安全而又方便的管理,但这建立在正确使用的前提下。为了正确使用智能指针,我们必须坚持一些基本规范:
1.不使用相同的内置指针初始化(或reset)多个智能指针;
2.不delete get( )返回的指针;
3.不使用get( )初始化或reset另一个智能指针;
4.如果你使用get( )返回的指针,记住当最后一个对应的智能指针销毁后,你的指针就变为无效了;
5.如果你使用智能指针管理的资源是new分配的内存,记住传递给它一个删除器。
https://blog.csdn.net/qq_33850438/article/details/52994314

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值