18.C++-[ ]操作符使用 、函数对象与普通函数区别(详解)
在上章17.C++-string字符串类(详解)学习了string类,发现可以通过[ ]重载操作符来访问每个字符。
比如:
string s="SAD"; for(int i=,i< s.length();i++)
cout<<s[i]<<endl;
接下来,我们来自己写个[ ]重载操作符,来模拟string类
#include <iostream>
#include "string.h" class string
{
private:
char *str;
int len; public:
string(const char *p=)
{
if(p!=NULL)
{
len=strlen(p);
str = new char[len];
strcpy(str,p);
}
else
{
len=;
str = new char[];
str[]='\0';
}
}
char& operator [](int i)
{
return str[i];
} int length()
{
return len;
}
}; int main()
{
string s="SAD";
for(int i=;i< s.length();i++)
std::cout << s[i] << std::endl; return ;
}
运行打印:
S
A
D
函数对象
- 函数对象是指该对象具备函数的行为
- 函数对象,是通过()调用操作符声明得到的,然后便能通过函数方式来调用该对象了.
- ()调用操作符可以定义不同参数的多个重载函数
- ()调用操作符只能通过类的成员函数重载(不能通过全局函数)
- 函数对象用于在工程中取代函数指针
比如,定义一个函数对象t:
class Test{
public:
void operator () (void) //通过()重载操作符,来使对象具备函数的行为
{
cout<<"hello"<<endl;
}
};
int main()
{
Test t;
t(); //打印"hello"
}
函数对象与普通函数区别
函数对象
可以封装自己的成员以及其它函数,所以能够更好的面向对象.
普通函数
往往只具备逻辑关系,并且没有固定的成员,因为普通函数一被调用完后,里面的内容便被摧毁了,除非使用全局变量,但是全局变量又不具备封装性.
接下来,我们来个普通函数和函数对象的示例,便知道两者的区别了.
需求如下:
- 通过一个函数,来获取斐波那契数列每项的值
- 每调用一次函数,便返回一个值
- 可以重复使用
普通函数实例:
#include <iostream>
using namespace std; int cnt0=;
int cnt1=; void fib_set(int n) //设置斐波那契数列为哪一项,使fib()能重复使用
{
cnt0=;
cnt1=;
for(int i=;i<n;i++)
{
int tmp=cnt1;
cnt1=cnt0+cnt1;
cnt0=tmp;
}
} int fib() //计算出一项值
{
int tmp=cnt1;
cnt1=cnt0+cnt1;
cnt0=tmp; return tmp;
} int main()
{
for(int i=;i<;i++)
cout<<fib()<<endl; //打印1~5项值 fib_set(); //从新设置项数位0 for(int i=;i<;i++)
cout<<fib()<<endl; //再次打印1~5项值,使它能重复使用 return ;
}
运行打印:
从上面代码可以看到,通过普通函数实现的需求,还需要两个全局变量才行,这在大项目里,完全不可取的,若项目里,像这样的模块多的话,那得有多少个全局变量啊?并且这些全局变量能够随意被破坏,没有一点封装性.
接下来,通过函数对象来完成这个需求:
#include <iostream>
using namespace std; class Fib{
private:
int cnt0;
int cnt1;
public:
Fib(int n=)
{
cnt0=;
cnt1=;
} void operator =(int n)
{
cnt0=;
cnt1=;
for(int i=;i<n;i++)
{
int tmp=cnt1;
cnt1+=cnt0;
cnt0=tmp;
}
} int operator () ()
{
int tmp=cnt1;
cnt1+=cnt0;
cnt0=tmp; return cnt0;
} }; int main()
{
Fib fib;
for(int i=;i<;i++)
cout<<fib()<<endl; //打印1~5项值 fib=; //从新设置项数为0 for(int i=;i<;i++)
cout<<fib()<<endl; //打印1~5项值 return ;
}
运行打印:
从上面代码看到,使用函数对象后,便不需要使用全局变量了.
18.C++-[ ]操作符使用 、函数对象与普通函数区别(详解)的更多相关文章
- python正则表达式函数match()和search()的区别详解
match()和search()都是python中的正则匹配函数,那这两个函数有何区别呢? match()函数只检测RE是不是在string的开始位置匹配, search()会扫描整个string查找 ...
- python中的函数对象与闭包函数
函数对象 在python中,一切皆对象,函数也是对象 在python语言中,声明或定义一个函数时,使用语句: def func_name(arg1,arg2,...): func_suite 当执行流 ...
- day16 函数对象与闭包函数
目录 一.函数对象 1.1函数可以被引用 1.2函数可以作为容器类型的元素 1.3函数可以作为参数传入另外一个函数 1.4函数的返回值可以是一个函数 二.闭包函数 1 什么是闭包函数 2 闭包函数的用 ...
- [概念] js的函数节流和throttle和debounce详解
js的函数节流和throttle和debounce详解:同样是实现了一个功能,可能有的效率高,有的效率低,这种现象在高耗能的执行过程中区分就比较明显.本章节一个比较常用的提高性能的方式,通常叫做&qu ...
- javascript 用函数语句和表达式定义函数的区别详解
通常我们会看到以下两种定义函数的方式: // 函数语句 function fn(str) { console.log(str); }; // 表达式定义 var fnx=function(str) { ...
- jQuery height()、innerHeight()、outerHeight()函数的区别详解
参考来源:http://www.jb51.net/article/84897.htm 代码示例(可复制到编辑器直接打开): <!DOCTYPE html> <html lang=&q ...
- C#类、对象、方法和属性详解
C#类.对象.方法和属性详解 一.相关概念: 1.对象:现实世界中的实体(世间万物皆对象) 2.类:具有相似属性和方法的对象的集合 3.面向对象程序设计的特点:封装 继承 多态 4.对象的三要素:属性 ...
- str_replace函数的使用规则和案例详解
str_replace函数的使用规则和案例详解 str_replace函数的简单调用: <?php $str = '苹果很好吃.'; //请将变量$str中的苹果替换成香蕉 $strg = st ...
- c++之函数对象、bind函数
函数对象实质上是一个实现了operator()--括号操作符--的类. class Add { public: int operator()(int a, int b) { return a + b; ...
随机推荐
- MySQL Crash Errcode: 28 - No space left on device
一台MySQL服务器突然Crash了,检查进程 ps -ef | grep -i mysql 发现mysqld进程已经没有了, 检查错误日志时发现MySQL确实Crash了.具体如下所示: 注意日志中 ...
- 嵌入式Linux引导过程之1.2——Xloader的XLOADER_ENTRY
根据上文中获得的线索,本文分析init.S中的XLOADER_ENTRY. 在init.S中,定义了好多与平台相关的寄存器地址宏以及好多其他函数,我们在用到的时候再回过头来分析,这里,我们只看其中的一 ...
- tcp为什么要三次握手,而不能二次握手?
谢希仁版<计算机网络>中的例子是这样的,"已失效的连接请求报文段"的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞 ...
- DirectX:函数可以连接任意两个filter
函数可以连接任意两个filter HRESULT ConnectFilters( IBaseFilter *pSrc, IBaseFilter *pDest ) { IPin *pIn = 0; IP ...
- 芝麻HTTP: Python爬虫利器之PyQuery的用法
前言 你是否觉得 XPath 的用法多少有点晦涩难记呢? 你是否觉得 BeautifulSoup 的语法多少有些悭吝难懂呢? 你是否甚至还在苦苦研究正则表达式却因为少些了一个点而抓狂呢? 你是否已经有 ...
- CF368 D - Persistent Bookcase
re了20多发 还是我在测试数据上操作最后了10多发才发现的 其实只需要多加一句就好了 真的愚蠢啊,要不都能进前100了 #include<bits/stdc++.h> using nam ...
- Struts2(七) Struts2访问Servlet的API
当接受表单参数,向页面保持数据时.要用到Struts访问Servlet 的API .下面只做参考,有错误或不同意见可以发送邮箱2440867831@qq.com .建议大家看struts文档,源代码 ...
- 消息中间件kafka+zookeeper集群部署、测试与应用
业务系统中,通常会遇到这些场景:A系统向B系统主动推送一个处理请求:A系统向B系统发送一个业务处理请求,因为某些原因(断电.宕机..),B业务系统挂机了,A系统发起的请求处理失败:前端应用并发量过大, ...
- mybatis快速入门(六)
前面mybatis的入门程序基本上都写完了,就看大家的灵活运用了,今天来吧前面的整合一下封装一个公共的BaseDao 只需要把前面的改造下然后创建一个BaseDao的接口,其它的继承BaseDao接口 ...
- C#中的函数式编程:序言(一)
学了那么久的函数式编程语言,一直想写一些相关的文章.经过一段时间的考虑,我决定开这个坑. 至于为什么选择C#,在我看来,编程语言分三类:一类是难以进行函数式编程的语言,这类语言包括Java6.C语言等 ...