By Reference
当以by reference方式传递对象当作函数参数,对象本身并不会被复制出一个副本——复制的是对象的地址,函数中对该对象进行的任何操作,都相当于是对传入的对象进行间接的操作。
将参数声明为reference的理由之一:希望得以直接对所传入的对象进行修改。这个理由极为重要,因为就像我们在前面的例子中所见,不这么做的话,程序无法正确运行。
将参数声明为reference的理由之二:为了降低复制大型对象的负担。这个理由相较起来不那么重要,因为对程序而言这不过是效率的问题罢了。
用const修饰by reference的参数:如果不加const修饰并不会错误,但是加上const修饰为的是让阅读程序的人了解,现在是要以传址的方式来传递参数,为的是避免复制操作,而不是为了要在函数中对它进行修改,同时也避免了对参数误修改的可能。
以pointer形式传递和以reference形式传递:两者的效用相同,都是传递对象地址,而不是整个对象的复制品。唯一区别在于用法不同,传递时一个需要加入取地址符(&),一个直接写变量名。两者之间的差异是,pointer可能(也可能不)指向某个实际对象。当使用pointer时,一定要先确认其值并非为0。至于reference则必定会代表某个对象,所以不须做此检查。
一般来说,除非希望在函数内更改参数值,否则建议在传递内建对象时(int, double...),不要使用传址方式。传址机制主要是作为传递class object之用。
Inline
将函数声明为inline,标识要求编译器在每个函数调用点上,将函数的内容展开。面对一个inline函数,编译器可将该函数的调用操作改以一份函数码副本取而代之。这使我们获得效率上的改善。一般而言,最适合声明为inline的函数,体积小,常被调用,所从事的计算并不复杂。
模板函数 Template Functions
function templates以关键词template开场,气候紧接着以成对尖括号(< >)包围起来的一个或多个识别名称。这些名称用法表示我们希望延缓决定的数据类型。每当用户利用这个模板产生函数时,他就必须提供确定的类别信息。这些识别名称事实上扮演着置物箱的角色,用来放置函数参数表及函数主体中的某些实际数据类型。例如:
template <typename elemType>
void display_message( const string &msg, const vector<elemType> &vec)
{
cout<<msg;
for(int ix = 0; ix < vec.size(); ix++)
{
elemtype t = vec[ix];
cout<<t<<' ' ;
}
}
关键词typename表示,elemType在display_message()函数中是一个临时放置类型的代称。elemType只是个任意名称。
应当如何使用function template呢?使用方式看起来和普通函数极为相似,举个例子,当我们写:
vector < int > ivec;
string msg;
//...
display_message ( msg, ivec);
时,编译器编译器会将elemType绑定(bind)为int类型,然后产生一份display_message()函数实体,于是其第二个的类型即变成vector<int>。参数实体的局部对象的类型同样也变成了int。