函数参数可分为三类,值传递也就是形参,指针传递也就是实参,同样还有引用传递
其中值传递很简单,本质上就是将函数参数的值复制一份,传递给函数。其实是创建了一个局部变量,这是一个新的变量。
而指针传递,同样是将函数参数的值复制一份,传递给函数,与值传递的区别在于,传进来的值是想要使用的变量的地址,同样定义了一个新的局部变量y来存储这个指针。如下面的代码块
void A(int x, int *y )
int main()
{
int x1 =0;
int y1 =1;
A(x1,&y1);
//此时在函数A中y的值应当是一个指针,如果cout<<y<<endl;得到的应该是一个地址,而非1
}
如上代码块,对于存储地址的y,它同样只是一个局部变量,正常情况下,你也无法通过修改y中存储的地址,来影响y1的地址,意思就是即使你在函数A中将y进行修改,你的修改只会持续到函数结束。但是你可以通过指针的方式对y1的值进行修改,并且修改这一行为是直接作用在y1身上的。
再说说关于引用传递,引用传递其实在底层是通过指针实现的,但是又包了一层,把指针包在的引用类型里面,将参数的地址封装在引用类型的变量中传递给函数。在函数内部可以通过引用来访问和修改原始变量的值,而这些修改也会在函数调用结束后保留在原始变量中。引用传递可以避免指针传递中的空指针问题。但是引用有一个地方需要注意,引用分为所谓的左值引用和右值引用,这个东西分别理解成为创造一个引用类型的变量和取地址就好了。
//一个引用的简单实现
template <typename T>
class Reference {
public:
// 构造函数,将引用与一个对象绑定
Reference(T& obj) : ptr_(&obj) {}
// 解引用操作符,返回引用指向的对象
T& operator*() const { return *ptr_; }
private:
T* ptr_; // 指向被引用的对象
};