一.函数对象的分析
Q:客户的需求
1.函数可以获得斐波那契数列每项的值
2.每调用一次返回一个值
3.函数可根据需求重复使用
for(int i=0;i<10;i++)
{
cout<<fib()<<endl;
}
代码示例
#include <iostream>
#include <string>
using namespace std;
int fib()
{
static int a0=0;
static int a1=1;
int ret=a1;
a1=a0+a1;
a0=ret;
return ret;
}
int main()
{
for(int i=0; i<10; i++)
{
cout << fib() << endl;
}
cout << endl;
for(int i=0; i<5; i++)
{
cout << fib() << endl;
}
cout << endl;
for(int i=0; i<5; i++)
{
cout << fib() << endl;
}
return 0;
}
输出的结果如图所示
从代码以及运行结果我们看到一些存在的问题
1.静态局部变量处于函数内部,外界无法改变
2.函数位全局变量,是唯一的,无法多次独立使用
3.无法指定某个具体的数列作为初始值
解决方案:使用函数对象
1.使用具体的对象取代函数
2.该类的对象具备函数调用的行为
3.构造函数指定具体数列项的起始位置
4.多个对象相互对立的求解数列项
函数的调用操作符
1.只能通过类的成员函数重载
2.可以定义不同参数的多个重载函数
代码示例
#include <iostream>
#include <string>
using namespace std;
class Fib
{
int a0;
int a1;
public:
Fib()
{
a0 = 0;
a1 = 1;
}
Fib(int n)
{
a0 = 0;
a1 = 1;
for(int i=2; i<=n; i++)
{
int t = a1;
a1 = a0 + a1;
a0 = t;
}
}
int operator () ()
{
int ret = a1;
a1 = a0 + a1;
a0 = ret;
return ret;
}
};
int main()
{
Fib fib;
for(int i=0; i<10; i++)
{
cout << fib() << endl;
}
cout << endl;
for(int i=0; i<5; i++)
{
cout << fib() << endl;
}
cout << endl;
Fib fib2(10);
for(int i=0; i<5; i++)
{
cout << fib2() << endl;
}
return 0;
}
运行结果如图所示
从多次的运行结果可以看出,对之前存在的问题进行改正,完成了需求
小结
1.函数调用操作符是可以重载的
2.函数调用操作符只能通过类的成员函数重载
3.函数调用操作符可以定义不同参数的多个重载指针
4.函数对象用于在工程中取代函数指针
二.经典问题分析
Q:关于赋值的疑问
1.编译器为每个类默认重载了赋值操作符
2.默认的赋值操作符仅完成浅拷贝
3.当需要进行深拷贝时必须重载赋值操作符
4.赋值操作符与拷贝构造函数有相同的存在意义
代码示例
#include <iostream>
#include <string>
using namespace std;
class Test
{
int* m_pointer;
public:
Test()
{
m_pointer = NULL;
}
Test(int i)
{
m_pointer = new int(i);
}
Test(const Test& obj)
{
m_pointer = new int(*obj.m_pointer);
}
void print()
{
cout << "m_pointer = " << hex << m_pointer << endl;
}
~Test()
{
delete m_pointer;
}
};
int main()
{
Test t1 = 1;
Test t2;
t2 = t1;
t1.print();
t2.print();
return 0;
}
运行结果如图所示
分析:在代码中由于将t1赋值给t2,导致t1与t2指向的是同一个地址,而在使用完之后,对内存进行释放时对同一个地址释放了两次,这个操作在计算机内部会造成错误
Q:关于string的疑问
下面的代码输出是什么?
string s="123456";
const char *p=s.c_str();
cout<<p<<endl;
s.append("abced");
cout<<p<<endl;
如上所示的代码想完成的是在字符串123456后面添加abced
可实际的运行结果如图所示
分析
小结
1.在需要进行深拷贝的时候必须重载赋值操作符
2.赋值操作符何拷贝构造函数又同等重要的意义
原文地址:https://blog.51cto.com/13475106/2411427
时间: 2024-11-05 10:20:37