C++进阶剖析( 十 七)之函数对象分析和智能指针

1.1 问题引出
1.1.1 需求
编写一个函数需要满足下面条件

  • 函数可以获得斐波那契数列的每一项的值
  • 每调用一次返回一个值
  • 函数可根据需要重复使用
for(int i =0 ;i< 10;i++)
{
cout<< fib() <<endl;
}

1.1.2 解决方案

#include <iostream>
using namespace std;

int  fib()
{
	static int a=0;
	static int b =1;
	int ret = b;
	b = a+b;
	a =ret;
	return ret;
}
int main()
{	
	for(int i= 0 ;i<10;i++)
	{
		cout<< fib()<<endl;
	}
	cout <<"============================\n";
	for(int i= 0 ;i<10;i++)
	{
		cout<< fib()<<endl;
	}

	return 0;
}

结果是:
在这里插入图片描述
从上面的运行结果来看,
函数一旦开始调用就无法重来

  • 静态局部变量处于函数内部,外界无法改变
  • 函数为全局函数,是唯一的,无法多次独立使用
  • 无法指定某个具体的数列项作为初始值

1.2 解决方案
1.2.1

#include <iostream>
using namespace std;

class Fib
{
private:
	 int a;
	 int b;
public:
	Fib()
	{
		a =0;
		b =1;
	}
	Fib(int n)
	{
		a=0;
		b=1;
		for(int i =2;i<=n;i++)
		{
			int ret = b;
			b = a +b;
			a =ret;
		
			
		}
	}
	int operator()()
	{
		int ret =b;
		b = a+b;
		a = ret;
		return ret;
	}
};


int main()
{	
	Fib fib;
	
	for(int i= 0 ;i<10;i++)
	{
		cout<< fib()<<endl;
	}
	cout <<"============================\n";
	Fib fib2(3);
	for(int i= 0 ;i<10;i++)
	{
		cout<< fib2()<<endl;
	}

	return 0;
}

1.3智能指针
1.3.1 内存泄漏

  • 动态申请堆空间,用完后补归还
  • C++语言中没有垃回收的机制
  • 指针无法控制所指堆空间的生命周期(指针变量和他所指向的内存空间变量是两个不同的变量)

1.3.2示例代码

#include<iostream>
#include<string>
using namespace std;
class Test
{
private:
	int i;
public:
	Test(int i)
	{
		this->i =i;
	}
	int value()
	{
		return i;
	}
	~Test()
	{}
};
int main()
{
	for(int i = 0;i<10;i++)
	{
		Test* p =new Test(i);  //指针变量和他所指向的内存空间变量是两个不同的变量
		cout<< p->value()<<endl;
	}
	return 0;
}

  • 上面的代码看着可以运行,没有问题,但是实际上有内存泄漏,不能长时间运行

1.3.3 深度思考

  • 我们需要什么
    • 我们需要一个特殊的指针
    • 指针生命周期结束时主动释放堆空间
    • 一片堆空间最大只能由一个指针标识
    • 杜绝指针运算和制造比较

1.3.4 解决方案

  • 重载指针特征操作符(-> 和*)
  • 只能通过类的成员函数重载
  • 重载函数不能使用参数
  • 只能定义一个重载函数
    注意智能指针使用军规 :只能用来指向堆空间中的对象或者变量
    1.3.5智能指针
  • 智能指针是使用对象来代替指针
class Test
{
private:
	int i;
public:
	Test(int i = 0)
	{
		cout<<"Test(int i)"<<endl;
		this->i =i;
	}
	int value()
	{
		return i;
	}
	~Test()
	{
		cout<<"~Test()"<<endl;
	}
};

class Pointer
{
private:
	Test *mp;
public:
	Pointer(Test* p = NULL)
	{
		mp = p;
	}
	Pointer(const Pointer& obj)
	{
		if(this != &obj)
		{
			mp = obj.mp;
			const_cast<Pointer&>(obj).mp =NULL; //这里一定要注意, obj有括号
		}
	}
	Pointer& operator= (const Pointer&obj)
	{
		if(this != &obj)
		{
			delete mp;
			mp = obj.mp;
			const_cast<Pointer&>(obj).mp =NULL;
		}
		return *this; 
	}
	Test * operator->()
	{
		return mp;
	}
	Test& operator*()
	{
		return *mp;
	}

	bool isNull()
	{
		return (mp == NULL);
	}
	~Pointer()
	{
		delete mp;
	}



};
int main()
{
	Pointer  p =new Test(10);
	cout<<p->value()<<endl;
	Pointer p2 =p;
	cout<< p.isNull()<<endl;
	cout<<p2->value()<<endl;
	return 0;
}

-运算结果
在这里插入图片描述

1.4
1.4.1

1.4.2

1.4.3

1.5
1.5.1

1.5.2

1.5.3

参考一 :狄泰软件学院C++进阶剖析
参考二 : C++ primer中文版
如有侵权:请联系邮箱 1986005934@qq.com

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值