c/c++ 中的传值调用和传引用
2009-06-03 17:23
204 查看
代码:
屏幕输出:
i= 0 j= 0
&i= 0x22ff6c &j= 0x22ff68
x= 0 y= 0
&x= 0x22ff6c &y= 0x22ff44
x= 1 y= 1
i= 1 j= 0
可以看到给函数 f() "传引用(pass by reference)"和"传值(pass by value)"在使用上类似,但实际中有很大区别:
"传值"传递的是原始变量 j 的一份拷贝 y,编译器为新的拷贝 y 重新分配了内存空间,因此本例中变量 j 和 变量 y 有不同的内存地址.对函数 f() 体内 y 的附新值,不会影响函数 f() 体外 j 的值.
"传引用"传递的是变量 i 的地址,并没有额外分配新的内存空间.x 就相当于 i 在 f() 体内的一个别名(我的理解),x 同 i 使用相同的地址空间,使用 x 就相当于引用了 i 的值,显然对 f() 体内 x 赋新值,就会影响到函数 f() 体外 i 的值.这点其实也就是我们使用"传引用"的目的之一,能影响 "outer object".
有的时候你希望引用函数如 f() 不能修改被引用的变量如 i,那么可以这样定义函数:
void f(const int& x, int y)
这样的话,如果你还是在 f() 里使用 x++,那么编译时就会提示你引用的是一个只读变量.
这是一种良好的编程习惯, 比起传值调用,优点在于不需要额外分配内存空间.
---------------------------------
引用实际上是一个常量指针,不会再指向别的对象。但在作为函数参数时,特别是在涉及对象时,引用比指针和传值有优势。如果对象采用传值方式传递,必然会调用自身的构造函数和并递归调用基类的构造函数。如果继承的层次多,这会造成很大的开销。但是在使用指针时,又会发生对象切片问题,所以在传递对象时,最好使用安全和高效的引用。
----------------------------------
对象切片问题:指在多态使用对象时,派生类对象在复制过程中发生向上类型转换,使得本来应该复制的是派生类对象,结果却只复制了派生类对象的基类对象部分,相当于派生类对象被切掉了一部分。
----------------------------------
传引用只有在传递对象时才有优势,引用本身也需要4个字节的空间,和int是一样的,所以传int是不应该使用引用的。
----------------------------
转帖自http://www.linuxsir.org/bbs/thread54887.html 特此感谢
// Reference.cpp // Different between pass by Reference and pass between value #include <iostream> using namespace std; void f(int&, int); main() { int i = 0, j = 0; cout << "i= " << i << "/t" << "j= " << j << endl; cout << "&i= " << &i << "/t" << "&j= " << &j << endl; f(i, j); cout << "i= " << i << "/t" << "j= " << j << endl; // wait(); return 0; } void f(int& x, int y) { cout << "x= " << x << "/t" << "y= " << y << endl; cout << "&x= " << &x << "/t" << "&y= " << &y << endl; x++; y++; cout << "x= " << x << "/t" << "y= " << y << endl; }
屏幕输出:
i= 0 j= 0
&i= 0x22ff6c &j= 0x22ff68
x= 0 y= 0
&x= 0x22ff6c &y= 0x22ff44
x= 1 y= 1
i= 1 j= 0
可以看到给函数 f() "传引用(pass by reference)"和"传值(pass by value)"在使用上类似,但实际中有很大区别:
"传值"传递的是原始变量 j 的一份拷贝 y,编译器为新的拷贝 y 重新分配了内存空间,因此本例中变量 j 和 变量 y 有不同的内存地址.对函数 f() 体内 y 的附新值,不会影响函数 f() 体外 j 的值.
"传引用"传递的是变量 i 的地址,并没有额外分配新的内存空间.x 就相当于 i 在 f() 体内的一个别名(我的理解),x 同 i 使用相同的地址空间,使用 x 就相当于引用了 i 的值,显然对 f() 体内 x 赋新值,就会影响到函数 f() 体外 i 的值.这点其实也就是我们使用"传引用"的目的之一,能影响 "outer object".
有的时候你希望引用函数如 f() 不能修改被引用的变量如 i,那么可以这样定义函数:
void f(const int& x, int y)
这样的话,如果你还是在 f() 里使用 x++,那么编译时就会提示你引用的是一个只读变量.
这是一种良好的编程习惯, 比起传值调用,优点在于不需要额外分配内存空间.
---------------------------------
引用实际上是一个常量指针,不会再指向别的对象。但在作为函数参数时,特别是在涉及对象时,引用比指针和传值有优势。如果对象采用传值方式传递,必然会调用自身的构造函数和并递归调用基类的构造函数。如果继承的层次多,这会造成很大的开销。但是在使用指针时,又会发生对象切片问题,所以在传递对象时,最好使用安全和高效的引用。
----------------------------------
对象切片问题:指在多态使用对象时,派生类对象在复制过程中发生向上类型转换,使得本来应该复制的是派生类对象,结果却只复制了派生类对象的基类对象部分,相当于派生类对象被切掉了一部分。
----------------------------------
传引用只有在传递对象时才有优势,引用本身也需要4个字节的空间,和int是一样的,所以传int是不应该使用引用的。
----------------------------
转帖自http://www.linuxsir.org/bbs/thread54887.html 特此感谢
相关文章推荐
- C++传值调用与引用调用的区别
- C++之传值调用和引用调用
- C++中const引用的是对象的时候只能调用该对象的f()const方法
- java及C++中传值传递、引用传递和指针方式的理解
- C++ 输入输出流的引用调用
- c#调用C++ dll 报未将对象引用到设置对象的实例 的解决方案
- 引用调用和传值调用
- C++——传引用调用
- C++学习笔记---利用对象、引用、指针调用虚函数
- C++箴言:用传引用给const取代传值
- c#中函数调用的按值传递和按引用传值
- C++的值调用和引用调用
- 【C/C++语法外功】传值&传引用&传指针
- Python函数调用“传引用”还是”传值“
- JNI进阶二(C++调用java数组 和 JNI引用)
- C++ 引用调用
- C++箴言:用传引用给const取代传值
- 详解python如何调用C/C++底层库与互相传值
- C++函数的传值调用&指针调用&引用调用
- Java中的形参和实参的区别以及传值调用和传引用调用