非引用形参和引用形参
指针形参
指针引用形参
总结:
非引用形参
(1)普通的非引用类型的参数通过复制对应的实参实现初始化。当用实参副本初始化形参时,函数并没有访问调用所传递的实参本身,因此不会修改实参的值。
(2)指针形参(也属于普通的非引用形参)
函数的形参可以是指针,此时将复制实参指针。与其他非引用类型的形参一样,该类形参的任何改变也仅作用于局部副本。如果函数将新指针值赋值给形参,主调函数使用的实参指针的值的动作等价。的值没有改变。但是可以改变形参指针所指对象的值,效果同利用实参的*来改变所指对象
(3)复制实参的局限性
复制实参并不是在所有情况下都适合,不适宜复制实参的情况包括:
当需要在函数中修改实参的值时。
当需要以大型对象作为实参传递时,复制对象所付出的时间和存储空间代价往往过大。
当没有办法实现对象的复制时。
对上述几种情况,有效的解决方法是将形参定义为引用或是指针类型。
引用形参
与所有引用一样,引用形参直接关联到其所绑定的对象。每次调用函数,引用形参被创建并与相应的实参关联。
引用
引用还可以用于定义一些函数,使它们既可以被用在赋值的左边,也可以用在右边。
例如:《STL源码剖析》红黑树那章中
Root( ) = header;
Leftmost( ) = header;
.《the c++ programming language》中举了这样一个例子,非常好:
定义Pair如下:
struct Pair{
string name;
double val;
};
基本想法就是让每个string有一个关联于它的浮点值。很容易定义一个函数value( ),让它维护一个Pair的数据结构,由曾经提供给它的所有不同的字符串组成。在此采用一个非常简单的且低效的实现:
vector<Pair> pairs;
double& value(const string& s)
{
for(int i = 0; i < pairs.size(); i++)
if(s == pairs[i].name) return pairs[i].val;
Pair p = {s, 0};
pairs.push_back(p);
return pairs[pairs.size()-1].val;
}
void main()
{
string buf;
while(cin>>buf) value(buf)++;
for(vector<Pair>::const_iterator p = pairs.begin(); p!= pairs.end(); ++p)
cout<<p->name<<":"<<p->val<<'\n';
}
这个功能可以被理解为一个浮点值数组,它以字符串为下标。对给定的参数串,value()找到对应的浮点对象(而不是浮点对象的值),返回到这个对象的一个引用。每次while循环从标准输入流cin将一个单词读入buf,并更新与它相关的计数器。最后结果的表里是输入中遇到的所有互不相同的词。最后将它们打印出来。例如:给定输入
aa bb bb aa aa bb aa aa
程序将产生:
aa :5
bb :3