一、函数的传递方式
1、值传递
形参是实参的拷贝,改变形参的值并不会改变外面实参的值,从一定的角度来说,值传递是单向的---------(实参---》形参),参数的值只能传入,不能传出。
应用场景:当函数内部需要修改参数,但是不影响调用者时,则用值传递。
void Test(int _nValue1, int _nValue2)//值传递
{
_nValue1 = 10;
_nValue2 = 20;
cout << "_nValue1:" << _nValue1 << endl;
cout << "_nValue2:" << _nValue2 << endl;
}
int main()
{
int i = 3, j = 5;
Test(i,j);
cout << "i:" << i << endl;
cout << "j:" << j << endl;
system("pause");
return 0;
}
执行结果:
2、引用传递
形参相当于是实参的“别名”,对形参的操作其实就是对实参的操作,在引用传递过程中,被调函数的形式参数虽然也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。
void Test(int &_nValue1, int &_nValue2)//引用传递
{
_nValue1 = 10;
_nValue2 = 20;
cout << "_nValue1:" << _nValue1 << endl;
cout << "_nValue2:" << _nValue2 << endl;
}
int main()
{
int i = 3, j = 5;
Test(i,j);
cout << "i:" << i << endl;
cout << "j:" << j << endl;
system("pause");
return 0;
}
执行后:
3、指针传递
形参为实参的地址指针,当对形参做改变时,也就是对实参做改变。
void Test(int *_nValue1, int *_nValue2)//指针传递
{
*_nValue1 = 10;
*_nValue2 = 20;
cout << "_nValue1:" << *_nValue1 << endl;
cout << "_nValue2:" << *_nValue2 << endl;
}
int main()
{
int i = 3, j = 5;
Test(&i,&j);
cout << "i:" << i << endl;
cout << "j:" << j << endl;
system("pause");
return 0;
}
执行后:
二、几种常见函数类型
1、静态成员函数
我们知道,c++的内存存储通常分为四个区:全局数据区,代码区,栈区,堆区。
全局数据区:存放全局变量,静态成员变量,和常量
代码区:存放类成员函数和非类成员函数。
栈区:为函数运行而存在的局部变量,函数参数,返回地址等。
堆区:除以上之外
按照这个说法,类成员函数是在声明定义时,放入代码区。类的静态成员变量一开始就放入了全局数据区。
而类的静态成员函数和非静态成员函数都是在类定义的时候放入了代码区。那为什么只有类才有直接调用类的静态成员函数,而非静态只有类对象能够调用。原因是类的非静态成员函数其实都含有一个指向类对象的this指针,因而只有类对象才能调用。
注意:new出来的只是成员变量,成员函数始终存在,所以如果成员函数未使用任何成员变量的话,不管是不是static的,都能正常工作。需要注意的是,虽然调用不同对象的成员函数时都是执行同一段函数代码,但是执行结果一般是不相同的。不同的对象使用的是同一个函数代码段,它怎么能够分别对不同对象中的数据进行操作呢?原来C++为此专门设立了一个名为this的指针,用来指向不同的对象。
2、回调函数
3、构造函数
拷贝构造函数
4、虚函数与纯虚函数