1、在函数重载中,主要通过参数类型的不同来重载,而不能通过返回值不同来重载。在函数的参数缺省值的设置中要注意不要和函数重载弄混,比如:
void output( int x);
void output( int x, float y=0.0);
这样就有二义行,如果有函数调用output(a)(a在这里为一整形数)时,不知道该调用哪个,产生错误!
2、在函数返回值为地址或引用时应该注意返回值不能是局部变量,应该是全局变量、静态变量等,静态变量(只在定义的局部函数里面可见)和全局变量共享全局数据区,在整个函数运行期间都存在,虽然用局部变量暂时可以得到正确的答案,如:
#include <iostream.h>
int *f(int x,int y)
{
int *z;
int temp=x+y;
z=&temp;
return z;
}
int f1()
{
cout<<"what wrong?"<<endl;
return 0;
}
int main()
{
int a,b;
int *c;
cin>>a>>b;
c=f(a,b);
cout<<*c<<endl;
f1();
cout<<*c;
return 0;
}
这个函数如果输入2,3则输出是:
5
what wrong?
-858993460
调用函数f1后再输出的c所指向的值是一个不确定的值,因为这个时候函数f已经结束,它用来返回的临时变量也在程序做了一些别的事情后被覆盖掉或释放。
3、参数传递传递指针和引用主要是为了效率,当一个数据类型很大时,因为传值要复制副本,所以不可取,但是另一方面由于指针和引用传递时参数容易被修改,所以我们在参数传递的时候加上关键字const用来限制调用函数对参数的改变。比如函数声明可以这样写:int fn(const int & a);则在这个函数里面,虽然a和实际参数指向的是同一地址单元,但是因为是const的,所以其值不可改变。
4、const int *ip;指向常量的指针,其指针值可以变,但是它所指内存中的值不可以改变(内存中的内容为常量);
int *const ip=&i;指针常量,其指针值不可以改变,但是它所指向内存中的值可以改变,并且在定义的时候需要赋初值;
const int *const ip=&i;指向常量的常量指针,定义时也需要初始化。
5、如果运算符被重载为全局函数,那么只有一个参数的运算符叫做一元运算符,有两个参数的运算符叫做二元运算符。如果运算符被重载为类的成员函数,那么一元运算符没有参数,二元运算符只有一个右侧参数,因为对象自己成了左侧参数。其中运算符的重载规则如下:
运算符 规则
所有的一元运算符 建议重载为成员函数
= () [] -> 只能重载为成员函数
+= -= /= *= &= |= ~= %= >>= <<= 建议重载为成员函数
所有其它运算符 建议重载为全局函数
6、this指针指向调用函数的那个对象。此条很容易解释第5条为什么运算符重载为类的成员函数时一元运算符没有参数,二元运算符只有一个右侧参数。
关于第2点的体会:
#include <iostream.h>
int *f(int x,int y)
{
int *z;
int temp=x+y;
z=&temp;
return z;
}
int f1()
{
cout<<"what wrong?"<<endl;
return 0;
}
int main()
{
int a,b;
int *c;
cin>>a>>b;
c=f(a,b);
cout<<*c<<endl;
f1();
cout<<*c;
return 0;
}
这个函数如果输入2,3则输出是:
5
what wrong?
-858993460
调用函数f1后再输出的c所指向的值是一个不确定的值,因为这个时候函数f()已经结束,它用来返回的临时变量也在程序做了一些别的事情后被覆盖掉或释放。
让我们来看这个很有趣的程序:
#include <iostream.h>
int *z;
int *f(int x,int y)
{
int temp=x+y;
z=&temp;
return z;
}
int f1()
{
cout<<"what wrong?"<<endl;
return 0;
}
int main()
{
int a,b;
int *c;
cin>>a>>b;
c=f(a,b);
cout<<*c<<endl;
f1();
cout<<*c;
return 0;
}
这里把z定义为全局的整形指针变量,然后把局部变量中x+y的值所指的地址给z返回,z为全局变量应该不存在上面临时变量被释放的情况,但实际上运行的到的结果出乎意料,还是:
5
what wrong?
-858993460
问题出在哪里?开始的时候我百思不得其解,甚至问老师老师也不太清楚,后来在网友的帮助下(看样子在网上学习很有用的)得到了答案,原来在函数f()中,temp是局部变量,在函数返回后它栈里面的值都要被释放,而指针z是指向局部变量temp的,所以得到上面的结果,于是将f()改成:
int *f(int x,int y)
{
*z=x+y;
return z;
}
再运行原以为可以得到正确的结果,但运行的时候出错了,再想想,原来定义全局指针变量z的时候并没有给它赋初值,这个时候指针的指向是不定的,所以运行时会出错,于是将定义改成int *z=new int;只是此时z成了堆中的数据,不再是放在全局数据区里面的了。
要想让全局数据区里面的数据返回被调函数的地址,可以把上面的全局变量声明改成int z;,函数f(x,y)中改成z=temp;return &z;就可以了。