不适宜复制实参的情况:
1)当需要在函数中修改实参的值时;
2)当需要以大型的对象作为实参时;
3)当没有办法实现对象复制时;
使用引用形参返回额外的信息
#include <iostream>
#include <vector>
using namespace std;
//函数说明:找出范围内特定的值出现的次数,并返回第一次出现的迭代器
vector<int>::const_iterator findVal(vector<int>::const_iterator begin,vector<int>::const_iterator end,int value,vector<int>::size_type &occurs)
{
vector<int>::const_iterator p=end;
occurs=0;
for(;begin!=end;++begin)
if(*begin==value)
{
if(p==end) p=begin;
++occurs;
}
return p;
}
int main()
{
vector<int> iVector;
vector<int>::size_type a;
iVector.push_back(1);
iVector.push_back(2);
iVector.push_back(3);
iVector.push_back(2);
vector<int>::const_iterator iter=findVal(iVector.begin(),iVector.end(),2,a);
cout << a<<*iter<<"Hello world!" << endl;
return 0;
}
如果使用引用形参的唯一目的是避免复制实参,则应该将形参定义为const引用。
应该将不需要修改的引用形参定义为const引用。普通的非const引用形参在使用时不太灵活。这样的形参既不能用const对象初始化,也不能用字面值或产生右值的表达式实参初始化。
通常函数应该有vector或其他标准库容器类型的形参。调用含有普通的非引用vector形参的函数将会复制vector的每一个元素。
将数组形参直接定义为指针要比使用数组语法定义要好,若设成数组形参,容易引起误解,造成越界错误。
不需要修改数组形参的元素师,函数应该将形参定义为指向const对象的指针。如:void f(const int *).
千万不要返回一个局部对象的引用。
求公约数(惠普实习生面试题):
#include <iostream>
#include <math.h>
using namespace std;
int rgcd1(int a,int b);//递归求解
int rgcd2(int a,int b);//迭代求解
int main()
{
cout<<rgcd1(9,6)<<endl;
cout<<rgcd2(16,12)<<endl;
cout << "Hello world!" << endl;
return 0;
}
int rgcd1(int a,int b)
{
if(b!=0) return rgcd1(b,a%b);
else return a;
}
int rgcd2(int a,int b)
{
int t;
if(b==0||a==0) return (abs(a-b));
t=a%b;
while(t)
{
a=b;b=t;t=a%b;
}
return b;
}
函数定义时,如果有一个形参具有默认实参,那么它后面所有的形参都必须有默认实参。
在设计带有默认实参函数的的时候,要注意排列形参,使最少使用默认实参的形参排列
在最前,最肯能使用默认实参的形参排在最后。
静态局部对象一旦被创建,在主程序结束前都不会撤销。可用作计数器。生命周期为整个源程序,但作用域与自动变量相同。
遵守一般的访问规则。
关于静态数据成员:对于所有的对象共有一个成员变量的就用static ,提供一个所有对象共有的一个成员变量比“每一个类对象维护一个成员变量” 要更有效。
每个类对象都有自己的拷贝而静态数据成员对每个类类型只有一个拷贝静态数据成员,只有一份由该类类型的所有对象共享访问。同全局对象相比使用静态数据成员有两个优势
1 静态数据成员没有进入程序的全局名字空间因此不存在与程序中其他全局名字冲突的可能性
2 可以实现信息隐藏静态成员可以是private 成员而全局对象不能
关于静态函数成员:
静态成员函数:使用static关键字声明的函数成员使静态的,静态成员函数同样也属于整个类,由同一个类的所有对象共同维护,为这些对象所共享.
内联函数(inline)
将小操作定义为函数的好处:
1)可读性好2)可维护性高3)可重用
定义为内联函数可以避免函数调用的开销
内联函数应当在头文件中定义。
类的成员函数既可以在类的定义内也可以在类的定义外,
编译器会隐式地将在类内定义的成员函数当作内联函数。
const成员函数在函数原型署名和函数定义中都要增加const限定,指明其为不改变对象的成员函数。
const对象,指针或引用只能用于调用其const成员函数,非const成员函数可能企图修改常量的数据成员。
重载函数:出现在相同作用域中的两个函数,具有相同的名字而形参不同,不能仅仅基于不同的返回类型而实现。
仅当形参是引用或指针时,形参是否为const才能影响。
指向函数的指针即函数的入口;例子如下:
#include <iostream>
using namespace std;
int max(int a,int b);
int main()
{
int c;
int (*p)(int,int);
p=max;
c=(*p)(9,6);
cout << c<<"Hello world!" << endl;
return 0;
}
int max(int a,int b)
{
return a>=b?a:b;
}
使用typedef能更直观地定义,
如typedef char (*PTRFUN)(int);
PTRRFUN pFun;
typedef的功能时定义新的类型,第一句就是定义了一种PTRFUN的类型,并定义这种类型为指向某种函数的指针,这种函数以一个int为参数,并返回char型,第二行使用此新类型定义了指针函数。
( 关于typedef的用法,详细请看这篇文章:http://www.cnblogs.com/charley_yang/archive/2010/12/15/1907384.html)
1)当需要在函数中修改实参的值时;
2)当需要以大型的对象作为实参时;
3)当没有办法实现对象复制时;
使用引用形参返回额外的信息
#include <iostream>
#include <vector>
using namespace std;
//函数说明:找出范围内特定的值出现的次数,并返回第一次出现的迭代器
vector<int>::const_iterator findVal(vector<int>::const_iterator begin,vector<int>::const_iterator end,int value,vector<int>::size_type &occurs)
{
vector<int>::const_iterator p=end;
occurs=0;
for(;begin!=end;++begin)
if(*begin==value)
{
if(p==end) p=begin;
++occurs;
}
return p;
}
int main()
{
vector<int> iVector;
vector<int>::size_type a;
iVector.push_back(1);
iVector.push_back(2);
iVector.push_back(3);
iVector.push_back(2);
vector<int>::const_iterator iter=findVal(iVector.begin(),iVector.end(),2,a);
cout << a<<*iter<<"Hello world!" << endl;
return 0;
}
如果使用引用形参的唯一目的是避免复制实参,则应该将形参定义为const引用。
应该将不需要修改的引用形参定义为const引用。普通的非const引用形参在使用时不太灵活。这样的形参既不能用const对象初始化,也不能用字面值或产生右值的表达式实参初始化。
通常函数应该有vector或其他标准库容器类型的形参。调用含有普通的非引用vector形参的函数将会复制vector的每一个元素。
将数组形参直接定义为指针要比使用数组语法定义要好,若设成数组形参,容易引起误解,造成越界错误。
不需要修改数组形参的元素师,函数应该将形参定义为指向const对象的指针。如:void f(const int *).
千万不要返回一个局部对象的引用。
求公约数(惠普实习生面试题):
#include <iostream>
#include <math.h>
using namespace std;
int rgcd1(int a,int b);//递归求解
int rgcd2(int a,int b);//迭代求解
int main()
{
cout<<rgcd1(9,6)<<endl;
cout<<rgcd2(16,12)<<endl;
cout << "Hello world!" << endl;
return 0;
}
int rgcd1(int a,int b)
{
if(b!=0) return rgcd1(b,a%b);
else return a;
}
int rgcd2(int a,int b)
{
int t;
if(b==0||a==0) return (abs(a-b));
t=a%b;
while(t)
{
a=b;b=t;t=a%b;
}
return b;
}
函数定义时,如果有一个形参具有默认实参,那么它后面所有的形参都必须有默认实参。
在设计带有默认实参函数的的时候,要注意排列形参,使最少使用默认实参的形参排列
在最前,最肯能使用默认实参的形参排在最后。
静态局部对象一旦被创建,在主程序结束前都不会撤销。可用作计数器。生命周期为整个源程序,但作用域与自动变量相同。
遵守一般的访问规则。
关于静态数据成员:对于所有的对象共有一个成员变量的就用static ,提供一个所有对象共有的一个成员变量比“每一个类对象维护一个成员变量” 要更有效。
每个类对象都有自己的拷贝而静态数据成员对每个类类型只有一个拷贝静态数据成员,只有一份由该类类型的所有对象共享访问。同全局对象相比使用静态数据成员有两个优势
1 静态数据成员没有进入程序的全局名字空间因此不存在与程序中其他全局名字冲突的可能性
2 可以实现信息隐藏静态成员可以是private 成员而全局对象不能
关于静态函数成员:
静态成员函数:使用static关键字声明的函数成员使静态的,静态成员函数同样也属于整个类,由同一个类的所有对象共同维护,为这些对象所共享.
静态成员函数一般只能访问静态成员变量,如果要访问非静态成员变量的话,只能访问某一个对象的非静态成员变量和静态成员函数。可以传一个对象的指针,引用等参数给这个静态成员函数。
在类的定义体外部引用类的static成员时,必须指定成员时哪个类中定义的。static关键字只能用于类定义体内部的声明中,定义不能标示为static。
内联函数(inline)
将小操作定义为函数的好处:
1)可读性好2)可维护性高3)可重用
定义为内联函数可以避免函数调用的开销
内联函数应当在头文件中定义。
类的成员函数既可以在类的定义内也可以在类的定义外,
编译器会隐式地将在类内定义的成员函数当作内联函数。
const成员函数在函数原型署名和函数定义中都要增加const限定,指明其为不改变对象的成员函数。
const对象,指针或引用只能用于调用其const成员函数,非const成员函数可能企图修改常量的数据成员。
重载函数:出现在相同作用域中的两个函数,具有相同的名字而形参不同,不能仅仅基于不同的返回类型而实现。
仅当形参是引用或指针时,形参是否为const才能影响。
指向函数的指针即函数的入口;例子如下:
#include <iostream>
using namespace std;
int max(int a,int b);
int main()
{
int c;
int (*p)(int,int);
p=max;
c=(*p)(9,6);
cout << c<<"Hello world!" << endl;
return 0;
}
int max(int a,int b)
{
return a>=b?a:b;
}
使用typedef能更直观地定义,
如typedef char (*PTRFUN)(int);
PTRRFUN pFun;
typedef的功能时定义新的类型,第一句就是定义了一种PTRFUN的类型,并定义这种类型为指向某种函数的指针,这种函数以一个int为参数,并返回char型,第二行使用此新类型定义了指针函数。
( 关于typedef的用法,详细请看这篇文章:http://www.cnblogs.com/charley_yang/archive/2010/12/15/1907384.html)