//本程序研究怎样进行对函数返回值操作而不影响实参,以及怎样让对函数返回值的操作影响到实参的值
//以及怎么禁止对函数返回值进行操作的几种方法。
#include<iostream>
using std::cout;
using std::cin;
using std::endl;
inline int &max1(int a,int b)
{
return a<b? b:a;
}
inline int &max2(int &a ,int &b)
{
return a<b? b:a;
}
inline int &max3(const int &a,const int &b)
{
return a<b? b:a;
}
inline int * max4(int *a ,int *b)
{
return *a<*b? b:a;
}
inline const int * max5(int *a , int *b)
{
return *a<*b? b:a;
}
inline const int &max6(int &a ,int &b)
{
return a<b? b:a;
}
void main()
{
int a=1,b=2,c=3,d=4;
int *p1=&a,*p2=&b,*p3=&c,*p4=&d;
cout<<"a,b调用函数++max1前a="<<a<<"/tb="<<b<<endl;
cout<<"++max1(a,b)本身的值为"<<++max1(a,b)<<endl;
cout<<"a,b调用函数++max1后a="<<a<<"/tb="<<b<<endl;
//对次函数max1的调用结果说明当参数传递为传值时,即使返回的是指针和引用,对返回值的操作也不会影响到
//原来的参数
cout<<"a,b调用函数++max2前a="<<a<<"/tb="<<b<<endl;
cout<<"++max2(a,b)本身的值为"<<++max2(a,b)<<endl;
cout<<"a,b调用函数++max2后a="<<a<<"/tb="<<b<<endl;
//对此函数max2的调用结果说明当参数和返回值都是引用的时候,对返回值的操作将改变实参的值
cout<<"c,d调用函数++max3前c="<<c<<"/td="<<d<<endl;
cout<<"++max3(c,d)本身的值为"<<++max3(c,d)<<endl;
cout<<"c,d调用函数++max3后c="<<c<<"/td="<<d<<endl;
//原来以为将max3的两个形参声明为const的引用,即使返回的是引用,对返回值的操作就不能改变实参
//但是结果确实改变了实参d的值,猜测原因就是对实参是引用的限制只在实参的那个作用域里面有效,也就是
//说只在函数体和那个实参列表中是const的引用,当函数返回以后对返回值操作不受const的限制了。因为对
//引用的说明就是在参数里声明的。
cout<<"p1,p2调用函数++(*max4(p1,p2))前a="<<*p1<<"/tb="<<*p2<<endl;
cout<<"++(*max4(p1,p2))本身的值为"<<++(*max4(p1,p2))<<endl;
cout<<"p1,p2调用函数++(*max4(p1,p2))后a="<<*p1<<"/tb="<<*p2<<endl;
//本段程序说明当参数和返回值都是指针的时候,对返回值的操作将改变实参的值
/*
cout<<"p1,p2调用函数++(*max5(p1,p2))前a="<<*p1<<"/tb="<<*p2<<endl;
cout<<"++(*max5(p1,p2))本身的值为"<<++(*max5(p1,p2))<<endl;
cout<<"p1,p2调用函数++(*max5(p1,p2))后a="<<*p1<<"/tb="<<*p2<<endl;
*/
//上面这段程序不能通过编译,因为*max5(p1,p2)返回的是一个const 指针,不能被修改。
/* cout<<"a,b调用函数++max6前a="<<a<<"/tb="<<b<<endl;
cout<<"++max6(a,b)本身的值为"<<++max6(a,b)<<endl;
cout<<"a,b调用函数++max6后a="<<a<<"/tb="<<b<<endl;
*/
//上面的这段程序也不能被编译,因为max6(a,b)返回的是一个const引用,不能被修改。
}
/*总结:(1)本程序使用了inline函数,以前都一直以为inline只可以用做类的成员函数
(2)通过本函数验证了只有在一种情况下对函数返回值的操作会影响到实参
1。参数是引用或指针(这个引用和指针可以是const的),返回值是引用或指针(这个引用或指针绝对
不能为const的),要同时满足这两个条件才可以。
(3)要避免对返回值的操作影响到实参,只要避免(2)的两个条件即可,尤其有效的是将返回值声明为
const的时候,这样任何试图对返回值的操作都将导致编译失败。如果既要对返回值进行操作,又要
操作结果不影响实参,可以使用传值的方式。
*/