C++语言中,对象作为函数的参数和返回值的传递方式有 3 种:值传递、指针传递和引用传递
对象作为函数参数
把实参对象的值复制给形参对象,这种传递是单向的,只从实参到形参。因此,函数对形参值做的改变不会影响到实参。
例如: 对象作为函数参数应用。
#include <iostream>
using namespace std;
class Square //正方形
{
public:
Square(double len) :length(len) //构造函数
{}
void set(double len) //修改边长
{
length = len;
}
double get()//获取边长的值
{
return length;
}
void show(); //输出面积
private:
double length;//边长
};
void Square::show() //输出面积
{
cout << "正方形面积:" << length * length << endl;
}
void Add(Square s)//只是修改形参的值,对实参没有影响
{
double len = s.get() + 1; //len=原边长+1;
s.set(len);//修改s的边长
}
int main()
{
Square s(2);
cout << "边长增加前:" << endl;
s.show();
Add(s);
cout << "边长增加后:" << endl;
s.show();
return 0;
}
对象指针作为函数参数
对象指针作为参数传递的是实参对象的地址。即实参对象指针和形参对象指针指向同一内存地址,因此若形参对象所指向成员数据的改变是可以影响实参数据成员的。
例如:修改上面的代码,验证对象指针作为函数参数可以修改实参的值
class Square //正方形
{
public:
Square(double len) :length(len) //构造函数
{}
void set(double len) //修改边长
{
length = len;
}
double get()//获取边长的值
{
return length;
}
void show(); //输出面积
private:
double length;//边长
};
void Square::show() //输出面积
{
cout << "正方形面积:" << length * length << endl;
}
void Add(Square *ps)//传递的是指针,形参可以修改实参的值
{
double len = ps->get() + 1; //len=原边长+1;
ps->set(len);//修改ps指向的边长
}
int main()
{
Square s(2);
cout << "边长增加前:" << endl;
s.show();
Add(&s);
cout << "边长增加后:" << endl;
s.show();
return 0;
}
对象引用作为函数参数
使用对象引用作为函数参数最常见,它不但有指针作为参数的优点,而且比指针作为参数更简单、更方便。 引用方式进行参数传递,形参对象就是实参对象的“别名”,对形参的操作其实就是对实参的操作。
例如:用对象引用进行参数传递。
class Square //正方形
{
public:
Square(double len) :length(len) //构造函数
{}
void set(double len) //修改边长
{
length = len;
}
double get()//获取边长的值
{
return length;
}
void show(); //输出面积
private:
double length;//边长
};
void Square::show() //输出面积
{
cout << "正方形面积:" << length * length << endl;
}
void Add(Square &s)//形参是引用,可以改变实参的值
{
double len = s.get() + 1; //len=原边长+1;
s.set(len);//修改ps指向的边长
}
int main()
{
Square squ(2);
cout << "边长增加前:" << endl;
squ.show();
Add(squ);
cout << "边长增加后:" << endl;
squ.show();
return 0;
}
三种传递方式比较
(1)值传递是单向的,形参的改变并不会引起实参的改变。而指针和引用传递是双向的,可以将改变由形参“传给”实参。
(2)引用是C++中的重要概念,引用的主要功能是传递函数的参数和返回值。学完这3种传递方式后大家会发现“引用传递”的性质像“指针传递”,而书写方式像“值传递”。
(3)指针能够毫无约束地操作内存中的任何东西。指针虽然功能强大,但是用起来比较困难,所以如果的确只需要借用一下某个对象的“别名”,建议使用“引用”,而不要用“指针”。
(4)使用引用作为函数参数与使用指针作为函数参数相比,前者更容易使用、更清晰。
例如:3种传递方式对比
//值传递
void increase1(int n)
{
cout << "值传递," << &n << endl;
n++;//修改形参的值
}
//引用传递
void increase(int& n)
{
cout << "引用传递," << &n <<endl;
n++;
}
//指针传递
void increase(int* n)
{
cout << "指针传递," << &*n<<endl;
*n = *n + 1;
}
int main()
{
int n = 10;
cout << "&n=" << &n<<",n="<<n<<endl;
increase1(n);
cout << "值传递,新n=" << n<<endl;
increase(n);
cout << "引用传递,新n=" << n<<endl;
increase(&n);
cout << "指针传递,新n=" << n << endl;
return 0;
}
说明:从代码效率上看,用对象值传递的方式的效率相对低一些,它需要创建新的对象来接收实参传来的值,用指针或者引用效率更高。
引用比指针使用起来更加简洁,方便,在C++中更常用。当然如果实参数据不能被修改,可以(应该)在前面加上const。
总结:在C++中引用传递是使用的最多的方式,如果数据不能修改请在参数前加const