我想问问各位大神,这样看来“按引用传参”是不是可以完全取代“按值传参”了呢?如果真的这样。按值传参的机制还有什么存在的意义呢?本人小菜,求指点!
49 个解决方案
#1
你完全用传引用代替值传递没什么问题,《Effective C++》中也是这样建议的。
#2
应用说类似于指针传参。
#3
用户自定义的类型最好用引用传参,这样可以避免不必要的构造函数和析构函数调用,但是对于像int,long,char一类的简单类型,按值传参也没有太多的开销,此时两种都可以
#4
如果都按引用传参的话需要注意实参被无意修改的可能(需要随时加const来限定),引用传参的实际意义多在参数较大时,降低系统开销
#5
这样可以避免不必要的构造函数和析构函数调用??求解释
#6
引用传参用得太多,代码看着别扭,对于对象较大,减少复制副本开支还是用引用好,个人愚见..
#7
传值还是有用处的
需要改变传入后的值,而无须改变传入前的值。 这样的需求引用传参就办不到
需要改变传入后的值,而无须改变传入前的值。 这样的需求引用传参就办不到
#8
引用传参一般是针对于类或者大的结构体,这样可以减少对象复制、创建时间。而引用看起来会比较别扭,也会让代码变的难以理解,所以一般基础类型(int , float 等等)都直接采用值传参,对于这种基础数据类型,采用引用或值传递的效率是差不多的。
如果总是采用引用传参,会导致一些问题,比如说,你要引用的那个对象的声明周期结束了呢?如果是值传递,就不用管先前那个对象是否还活着,如果是引用,就得注意这些问题。
如果总是采用引用传参,会导致一些问题,比如说,你要引用的那个对象的声明周期结束了呢?如果是值传递,就不用管先前那个对象是否还活着,如果是引用,就得注意这些问题。
#9
《Effective C++》条款22:尽量用"传引用"代替"传值"
http://riddickbryant.iteye.com/blog/569055
引用几乎都是通过指针来实现的,所以通过引用传递对象实际上是传递指针。因此,如果是一个很小的对象——例如int——传值实际上会比传引用更高效。
http://riddickbryant.iteye.com/blog/569055
引用几乎都是通过指针来实现的,所以通过引用传递对象实际上是传递指针。因此,如果是一个很小的对象——例如int——传值实际上会比传引用更高效。
#10
引用传参和指针传参差不多!如果仅需要有一个返回值的话,按值传参的效率应该会更高些!如果不加const 不至于对主函数的值进行修改!
同意楼上说的,对于内置类型,按值传参的效率更高些!
同意楼上说的,对于内置类型,按值传参的效率更高些!
#11
相当于指针的复制,但远远比对象的复制好,因为32位机指针才4字节,一般对象远远不只4字节。
#12
引用传递,只是明面上,没有使用值传递,值传递本身是不可避免的
编译器,暗地里通过指针(或者其他可以替代指针的数据类型)的值传递,替换了引用传递
所以引用传递,实质上是地址传递,别名这东西只是概念,是一种抽象,别名是没法传递的。
别名,可不是真实的数据类型哦。
因为,函数传递参数需要,数据复制,所以明的暗的值传递,不可避免。
如果采用全局变量,传递参数,那么函数调用,就可以避免直接数据复制了。
不过使用全局变量,这,,,引入的问题,比解决的问题还多。
引用的高效,在于对大的数据,不用直接的复制数据。
函数调用的语义,接近于值传递的语义
即 void fun(const A & a) ; 和 void fun (int a) ;的调用形式一致都是 fun(a);
编译器,暗地里通过指针(或者其他可以替代指针的数据类型)的值传递,替换了引用传递
所以引用传递,实质上是地址传递,别名这东西只是概念,是一种抽象,别名是没法传递的。
别名,可不是真实的数据类型哦。
因为,函数传递参数需要,数据复制,所以明的暗的值传递,不可避免。
如果采用全局变量,传递参数,那么函数调用,就可以避免直接数据复制了。
不过使用全局变量,这,,,引入的问题,比解决的问题还多。
引用的高效,在于对大的数据,不用直接的复制数据。
函数调用的语义,接近于值传递的语义
即 void fun(const A & a) ; 和 void fun (int a) ;的调用形式一致都是 fun(a);
#13
#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;
struct node
{
int *p1;
double *p2;
node()
{
p1 = new int();
p2 = new double();
*p1 = 0;
*p2 = 0.0;
cout << "Execute node's constructor." << endl;
}
node(const node &_node)
{
cout << "Execute node's copy constructor." << endl;
if(this == &_node)
{
return;
}
this->p1 = new int();
this->p2 = new double();
*p1 = *_node.p1;
*p2 = *_node.p2;
}
node& operator=(const node &_node)
{
cout << "Execute node's assignment operator function." << endl;
if(this == &_node)
{
return *this;
}
this->p1 = new int();
this->p2 = new double();
*p1 = *_node.p1;
*p2 = *_node.p2;
return *this;
}
~node()
{
delete p1;
delete p2;
p1 = 0;
p2 = 0;
}
};
void displayNode1(node _p)
{
cout << (*_p.p1) << endl;
cout << (*_p.p2) << endl;
}
void displayNode2(node &_p)
{
cout << (*_p.p1) << endl;
cout << (*_p.p2) << endl;
}
int main()
{
node p1;
cout << "Execute the display function not using reference." << endl;
displayNode1(p1);
node p2;
cout << "Execute the display function using reference." << endl;
displayNode2(p2);
return 0;
}
输出为
Execute node's constructor.
Execute the display function not using reference.
Execute node's copy constructor.
0
0
Execute node's constructor.
Execute the display function using reference.
0
0
#14
对于外界不希望值被修改,而函数内部会修改参数的值的情况。用const& ,函数内部也会再显示构一临时对象。就没必要用引用了。而且一般小的数据类型比如整型、字符型,如果不是为了把参数的值修改了再传出来,一般不会用引用
#15
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……
对学习编程者的忠告:
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步对应汇编一行!
VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
对学习编程者的忠告:
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步对应汇编一行!
VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
#16
不要纠结各种常量了,这个世界上唯一不变的就是变化。用API WriteProcessMemory还能修改正运行的其它进程的内存里面的所谓常量呢!
#17
传值还是有用处的
需要改变传入后的值,而无须改变传入前的值。 这样的需求引用传参就办不到
#18
《Effective C++》条款22:尽量用"传引用"代替"传值"
http://riddickbryant.iteye.com/blog/569055
引用几乎都是通过指针来实现的,所以通过引用传递对象实际上是传递指针。因此,如果是一个很小的对象——例如int——传值实际上会比传引用更高效。
#19
对于外界不希望值被修改,而函数内部会修改参数的值的情况。用const& ,函数内部也会再显示构一临时对象。就没必要用引用了。而且一般小的数据类型比如整型、字符型,如果不是为了把参数的值修改了再传出来,一般不会用引用
#20
其实很好理解,假设你要传的是一个Byte类型的变量,这时候用引用还不如传值吧
#21
引用传递,只是明面上,没有使用值传递,值传递本身是不可避免的
编译器,暗地里通过指针(或者其他可以替代指针的数据类型)的值传递,替换了引用传递
所以引用传递,实质上是地址传递,别名这东西只是概念,是一种抽象,别名是没法传递的。
别名,可不是真实的数据类型哦。
因为,函数传递参数需要,数据复制,所以明的暗的值传递,不可避免。
如果采用全局变量,传递参数,那么函数调用,就可以避免直接数据复制了。
不过使用全局变量,这,,,引入的问题,比解决的问题还多。
引用的高效,在于对大的数据,不用直接的复制数据。
函数调用的语义,接近于值传递的语义
即 void fun(const A & a) ; 和 void fun (int a) ;的调用形式一致都是 fun(a);
这位仁兄说的很详细很全面
#22
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……
对学习编程者的忠告:
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步对应汇编一行!
VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
话说,我跳的有点快。直接就学C然后就是C++,对于很么计算机原理不甚了解,对于网络更是一窍不通。。。。怎么破?
#23
其实很好理解,假设你要传的是一个Byte类型的变量,这时候用引用还不如传值吧
我可以问为什么吗?
#24
等你以后就知道了,呵呵
#25
zhao4zhong1 的回复总是那么霸气
#26
碰到数组引用就呵呵了
#27
碰到数组引用就呵呵了
数组一样有引用形式(不是引用数组中某个元素,而是整个数组),而且恰好是数组不能整体的当作一个参数传给函数。你把他隐式转换成指针再传的话,长度信息将会丢失
#28
传值有这么几个作用:
- 函数内部需要用到改变的传入参数,却不希望源参数的内容被修改
- 值传递会导致忽略实参的cv属性,这样对写函数重载有好处,如果有两个形参的类型一样,而实参传入时的cv属性不同,不至于导致重载匹配的失败
当然如果打算用值传递的话,拷贝开销就是避免不了的问题了。
- 函数内部需要用到改变的传入参数,却不希望源参数的内容被修改
- 值传递会导致忽略实参的cv属性,这样对写函数重载有好处,如果有两个形参的类型一样,而实参传入时的cv属性不同,不至于导致重载匹配的失败
当然如果打算用值传递的话,拷贝开销就是避免不了的问题了。
#29
内置类型建议使用pass by value
#30
如果按值传参,那么在递归函数回溯时就无需手动对参数进行还原。而传引用的话,改变的参数值必须在回溯时手动还原,这很容易出错,这算一个实用型的小意义吧
#31
像这种需求, 引用就没有这么方便了.
class MyClass
{
public:
int m_a;
}
int fun( MyClass a)
{
a.m_a = 100;
return a.m_a;
}
想使用a, 但是又不想改变外部的a, 但又能在内部直接对a对象的现有数据进行操作. 这时就只能用传值了.
你传引用,或者常引用都不能办到.
当然, 你说我可以在函数内,再定义一个对象, 把引用的对象复制一遍, 愿意这样做, 那我也无话可说.
class MyClass
{
public:
int m_a;
}
int fun( MyClass a)
{
a.m_a = 100;
return a.m_a;
}
想使用a, 但是又不想改变外部的a, 但又能在内部直接对a对象的现有数据进行操作. 这时就只能用传值了.
你传引用,或者常引用都不能办到.
当然, 你说我可以在函数内,再定义一个对象, 把引用的对象复制一遍, 愿意这样做, 那我也无话可说.
#32
碰到数组引用就呵呵了
数组一样有引用形式(不是引用数组中某个元素,而是整个数组),而且恰好是数组不能整体的当作一个参数传给函数。你把他隐式转换成指针再传的话,长度信息将会丢失
#33
C++中引入了按 引用传参的机制,实际上就是对实参起了一个别名,达到直接控制实参的目的。与按 值传参的方法相比,避免了开辟实参副本的时空开销。还可以可以通过const对是否允许改变实参进行控制。
我想问问各位大神,这样看来“按引用传参”是不是可以完全取代“按值传参”了呢?如果真的这样。按值传参的机制还有什么存在的意义呢?本人小菜,求指点!
语法规则而已,传递引用实际还是传递一个指针,只是在函数中按照引用的规则使用传人的参数而已
#34
咋没人将整个互联网内容引用传参给一个函数呢?
#35
非引用类型的copy-initialization保证对象的复制或转移。如果只传引用,除去函数引用你还可能得自己维护对象的生存期——很多时候明显多此一举。对于C++,传递对象引用特别地强调调用者在乎并且想避免对象的复制初始化——通常是基于开销或者同一性考虑。如果目的不是修改对象(使用左值引用),对象自身没有共享的可变状态,复制开销可以接受,那么没理由使用引用传递;典型地如内建类型的整数。
撇开C++不讲,call by reference相对call by value在很多时候能让调用变得更加简洁——例如Y combinator可以省掉CBV形式的eta conversion。代价类似:变量没法和lexical scope绑定确定生存期。
科普:
http://en.wikipedia.org/wiki/Evaluation_strategy
撇开C++不讲,call by reference相对call by value在很多时候能让调用变得更加简洁——例如Y combinator可以省掉CBV形式的eta conversion。代价类似:变量没法和lexical scope绑定确定生存期。
科普:
http://en.wikipedia.org/wiki/Evaluation_strategy
#36
有很多同胞告诉我:引用传参实际还是传递一个指针,所以对于一些小字节的数据,没必要用“引用传参”。
可是我在网上看到这样的话:传递变量的指针。形参是指针变量,实参是一个变量的地址,调用函数时,形参(指针变量)指向实参变量单元。这种“虚实结合”的方法仍然是“值传递”方式,只是实参的值是变量的地址而已。通过形参指针变量访问主函数中的变量(i和j),并改变它们的值。(这样就能得到正确结果,但是在概念上却是兜了一个圈子,不那么直截了当。)
这段话,明确的指出:引用传参并非传递变量的指针。有没有大神出来,解释下。这两种传参方式又有什么区别呢?
可是我在网上看到这样的话:传递变量的指针。形参是指针变量,实参是一个变量的地址,调用函数时,形参(指针变量)指向实参变量单元。这种“虚实结合”的方法仍然是“值传递”方式,只是实参的值是变量的地址而已。通过形参指针变量访问主函数中的变量(i和j),并改变它们的值。(这样就能得到正确结果,但是在概念上却是兜了一个圈子,不那么直截了当。)
这段话,明确的指出:引用传参并非传递变量的指针。有没有大神出来,解释下。这两种传参方式又有什么区别呢?
#37
内置类型建议使用pass by value
说法好洋气
#38
传值有这么几个作用:
- 函数内部需要用到改变的传入参数,却不希望源参数的内容被修改
- 值传递会导致忽略实参的cv属性,这样对写函数重载有好处,如果有两个形参的类型一样,而实参传入时的cv属性不同,不至于导致重载匹配的失败
当然如果打算用值传递的话,拷贝开销就是避免不了的问题了。
我可以问:cv是什么吗?请原谅我的无知。
#39
传值有这么几个作用:
- 函数内部需要用到改变的传入参数,却不希望源参数的内容被修改
- 值传递会导致忽略实参的cv属性,这样对写函数重载有好处,如果有两个形参的类型一样,而实参传入时的cv属性不同,不至于导致重载匹配的失败
当然如果打算用值传递的话,拷贝开销就是避免不了的问题了。
我可以问:cv是什么吗?请原谅我的无知。
标准中规定必须有的目前只有const和volatile这两个(就是这个所谓的“cv”)。但是允许编译器 在此基础上再扩展一些(比如大部分机器上需要支持aligned属性),这些扩展的属性和const和volatile一起称作"cv属性"(而不是仅仅const和volatile这两个)
#40
有很多同胞告诉我:引用传参实际还是传递一个指针,所以对于一些小字节的数据,没必要用“引用传参”。
可是我在网上看到这样的话:传递变量的指针。形参是指针变量,实参是一个变量的地址,调用函数时,形参(指针变量)指向实参变量单元。这种“虚实结合”的方法仍然是“值传递”方式,只是实参的值是变量的地址而已。通过形参指针变量访问主函数中的变量(i和j),并改变它们的值。(这样就能得到正确结果,但是在概念上却是兜了一个圈子,不那么直截了当。)
这段话,明确的指出:引用传参并非传递变量的指针。有没有大神出来,解释下。这两种传参方式又有什么区别呢?
CBV和CBR本来就两回事。
只不过在需要保持恒定调用约定以保持公开的二进制兼容性,不进行程序变换为基础的优化的前提下,在实现意义上传递C++内建指针和传递C++内建引用类型的参数生成的代码效果类似。具体会怎么样随实现高兴,和C++本身做了什么(抽象机为基础的基本语义)已经无关了。
“实参的值是变量的地址”纯属扯淡,基本上就没搞清楚值有类型而地址不考虑类型的基本概念。
#41
传值有这么几个作用:
- 函数内部需要用到改变的传入参数,却不希望源参数的内容被修改
- 值传递会导致忽略实参的cv属性,这样对写函数重载有好处,如果有两个形参的类型一样,而实参传入时的cv属性不同,不至于导致重载匹配的失败
当然如果打算用值传递的话,拷贝开销就是避免不了的问题了。
我可以问:cv是什么吗?请原谅我的无知。
标准中规定必须有的目前只有const和volatile这两个(就是这个所谓的“cv”)。但是允许编译器 在此基础上再扩展一些(比如大部分机器上需要支持aligned属性),这些扩展的属性和const和volatile一起称作"cv属性"(而不是仅仅const和volatile这两个)
准确地说cv就只是指const和volatile这两个限定符(qualifier) 。其它语法地位相当的限定符不会称为cv。
同样是限定符的,在ISO C中还有restrict和_Atomic。
#42
内置类型还是传值效率高
#43
坐看各大牛人语录,哈哈!!长见识啊
#44
MARK一下,回去慢慢看。。
#45
看各位大神讨论,学习了
#46
看各位大神讨论,学习了
#47
听得我好乱,还有谁有想法。来说啊!
#48
内置类型建议使用pass by value
说法好洋气
这些术语还是原始的比较好。
#49
内置类型建议使用pass by value
说法好洋气
这些术语还是原始的比较好。
#1
你完全用传引用代替值传递没什么问题,《Effective C++》中也是这样建议的。
#2
应用说类似于指针传参。
C++中引入了按 引用传参的机制,实际上就是对实参起了一个别名,达到直接控制实参的目的。与按 值传参的方法相比,避免了开辟实参副本的时空开销。还可以可以通过const对是否允许改变实参进行控制。
我想问问各位大神,这样看来“按引用传参”是不是可以完全取代“按值传参”了呢?如果真的这样。按值传参的机制还有什么存在的意义呢?本人小菜,求指点!
#3
用户自定义的类型最好用引用传参,这样可以避免不必要的构造函数和析构函数调用,但是对于像int,long,char一类的简单类型,按值传参也没有太多的开销,此时两种都可以
#4
如果都按引用传参的话需要注意实参被无意修改的可能(需要随时加const来限定),引用传参的实际意义多在参数较大时,降低系统开销
#5
用户自定义的类型最好用引用传参,这样可以避免不必要的构造函数和析构函数调用,但是对于像int,long,char一类的简单类型,按值传参也没有太多的开销,此时两种都可以
#6
引用传参用得太多,代码看着别扭,对于对象较大,减少复制副本开支还是用引用好,个人愚见..
#7
传值还是有用处的
需要改变传入后的值,而无须改变传入前的值。 这样的需求引用传参就办不到
需要改变传入后的值,而无须改变传入前的值。 这样的需求引用传参就办不到
#8
引用传参一般是针对于类或者大的结构体,这样可以减少对象复制、创建时间。而引用看起来会比较别扭,也会让代码变的难以理解,所以一般基础类型(int , float 等等)都直接采用值传参,对于这种基础数据类型,采用引用或值传递的效率是差不多的。
如果总是采用引用传参,会导致一些问题,比如说,你要引用的那个对象的声明周期结束了呢?如果是值传递,就不用管先前那个对象是否还活着,如果是引用,就得注意这些问题。
如果总是采用引用传参,会导致一些问题,比如说,你要引用的那个对象的声明周期结束了呢?如果是值传递,就不用管先前那个对象是否还活着,如果是引用,就得注意这些问题。
#9
《Effective C++》条款22:尽量用"传引用"代替"传值"
http://riddickbryant.iteye.com/blog/569055
引用几乎都是通过指针来实现的,所以通过引用传递对象实际上是传递指针。因此,如果是一个很小的对象——例如int——传值实际上会比传引用更高效。
http://riddickbryant.iteye.com/blog/569055
引用几乎都是通过指针来实现的,所以通过引用传递对象实际上是传递指针。因此,如果是一个很小的对象——例如int——传值实际上会比传引用更高效。
#10
引用传参和指针传参差不多!如果仅需要有一个返回值的话,按值传参的效率应该会更高些!如果不加const 不至于对主函数的值进行修改!
同意楼上说的,对于内置类型,按值传参的效率更高些!
同意楼上说的,对于内置类型,按值传参的效率更高些!
#11
相当于指针的复制,但远远比对象的复制好,因为32位机指针才4字节,一般对象远远不只4字节。
#12
引用传递,只是明面上,没有使用值传递,值传递本身是不可避免的
编译器,暗地里通过指针(或者其他可以替代指针的数据类型)的值传递,替换了引用传递
所以引用传递,实质上是地址传递,别名这东西只是概念,是一种抽象,别名是没法传递的。
别名,可不是真实的数据类型哦。
因为,函数传递参数需要,数据复制,所以明的暗的值传递,不可避免。
如果采用全局变量,传递参数,那么函数调用,就可以避免直接数据复制了。
不过使用全局变量,这,,,引入的问题,比解决的问题还多。
引用的高效,在于对大的数据,不用直接的复制数据。
函数调用的语义,接近于值传递的语义
即 void fun(const A & a) ; 和 void fun (int a) ;的调用形式一致都是 fun(a);
编译器,暗地里通过指针(或者其他可以替代指针的数据类型)的值传递,替换了引用传递
所以引用传递,实质上是地址传递,别名这东西只是概念,是一种抽象,别名是没法传递的。
别名,可不是真实的数据类型哦。
因为,函数传递参数需要,数据复制,所以明的暗的值传递,不可避免。
如果采用全局变量,传递参数,那么函数调用,就可以避免直接数据复制了。
不过使用全局变量,这,,,引入的问题,比解决的问题还多。
引用的高效,在于对大的数据,不用直接的复制数据。
函数调用的语义,接近于值传递的语义
即 void fun(const A & a) ; 和 void fun (int a) ;的调用形式一致都是 fun(a);
#13
这样可以避免不必要的构造函数和析构函数调用??求解释
用户自定义的类型最好用引用传参,这样可以避免不必要的构造函数和析构函数调用,但是对于像int,long,char一类的简单类型,按值传参也没有太多的开销,此时两种都可以
#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;
struct node
{
int *p1;
double *p2;
node()
{
p1 = new int();
p2 = new double();
*p1 = 0;
*p2 = 0.0;
cout << "Execute node's constructor." << endl;
}
node(const node &_node)
{
cout << "Execute node's copy constructor." << endl;
if(this == &_node)
{
return;
}
this->p1 = new int();
this->p2 = new double();
*p1 = *_node.p1;
*p2 = *_node.p2;
}
node& operator=(const node &_node)
{
cout << "Execute node's assignment operator function." << endl;
if(this == &_node)
{
return *this;
}
this->p1 = new int();
this->p2 = new double();
*p1 = *_node.p1;
*p2 = *_node.p2;
return *this;
}
~node()
{
delete p1;
delete p2;
p1 = 0;
p2 = 0;
}
};
void displayNode1(node _p)
{
cout << (*_p.p1) << endl;
cout << (*_p.p2) << endl;
}
void displayNode2(node &_p)
{
cout << (*_p.p1) << endl;
cout << (*_p.p2) << endl;
}
int main()
{
node p1;
cout << "Execute the display function not using reference." << endl;
displayNode1(p1);
node p2;
cout << "Execute the display function using reference." << endl;
displayNode2(p2);
return 0;
}
输出为
Execute node's constructor.
Execute the display function not using reference.
Execute node's copy constructor.
0
0
Execute node's constructor.
Execute the display function using reference.
0
0
#14
对于外界不希望值被修改,而函数内部会修改参数的值的情况。用const& ,函数内部也会再显示构一临时对象。就没必要用引用了。而且一般小的数据类型比如整型、字符型,如果不是为了把参数的值修改了再传出来,一般不会用引用
#15
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……
对学习编程者的忠告:
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步对应汇编一行!
VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
对学习编程者的忠告:
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步对应汇编一行!
VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
#16
不要纠结各种常量了,这个世界上唯一不变的就是变化。用API WriteProcessMemory还能修改正运行的其它进程的内存里面的所谓常量呢!
#17
传值还是有用处的
需要改变传入后的值,而无须改变传入前的值。 这样的需求引用传参就办不到
#18
《Effective C++》条款22:尽量用"传引用"代替"传值"
http://riddickbryant.iteye.com/blog/569055
引用几乎都是通过指针来实现的,所以通过引用传递对象实际上是传递指针。因此,如果是一个很小的对象——例如int——传值实际上会比传引用更高效。
#19
对于外界不希望值被修改,而函数内部会修改参数的值的情况。用const& ,函数内部也会再显示构一临时对象。就没必要用引用了。而且一般小的数据类型比如整型、字符型,如果不是为了把参数的值修改了再传出来,一般不会用引用
#20
其实很好理解,假设你要传的是一个Byte类型的变量,这时候用引用还不如传值吧
#21
引用传递,只是明面上,没有使用值传递,值传递本身是不可避免的
编译器,暗地里通过指针(或者其他可以替代指针的数据类型)的值传递,替换了引用传递
所以引用传递,实质上是地址传递,别名这东西只是概念,是一种抽象,别名是没法传递的。
别名,可不是真实的数据类型哦。
因为,函数传递参数需要,数据复制,所以明的暗的值传递,不可避免。
如果采用全局变量,传递参数,那么函数调用,就可以避免直接数据复制了。
不过使用全局变量,这,,,引入的问题,比解决的问题还多。
引用的高效,在于对大的数据,不用直接的复制数据。
函数调用的语义,接近于值传递的语义
即 void fun(const A & a) ; 和 void fun (int a) ;的调用形式一致都是 fun(a);
这位仁兄说的很详细很全面
#22
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构……
对学习编程者的忠告:
眼过千遍不如手过一遍!
书看千行不如手敲一行!
手敲千行不如单步一行!
单步源代码千行不如单步对应汇编一行!
VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
话说,我跳的有点快。直接就学C然后就是C++,对于很么计算机原理不甚了解,对于网络更是一窍不通。。。。怎么破?
#23
其实很好理解,假设你要传的是一个Byte类型的变量,这时候用引用还不如传值吧
我可以问为什么吗?
#24
等你以后就知道了,呵呵
#25
zhao4zhong1 的回复总是那么霸气
#26
碰到数组引用就呵呵了
#27
碰到数组引用就呵呵了
数组一样有引用形式(不是引用数组中某个元素,而是整个数组),而且恰好是数组不能整体的当作一个参数传给函数。你把他隐式转换成指针再传的话,长度信息将会丢失
#28
传值有这么几个作用:
- 函数内部需要用到改变的传入参数,却不希望源参数的内容被修改
- 值传递会导致忽略实参的cv属性,这样对写函数重载有好处,如果有两个形参的类型一样,而实参传入时的cv属性不同,不至于导致重载匹配的失败
当然如果打算用值传递的话,拷贝开销就是避免不了的问题了。
- 函数内部需要用到改变的传入参数,却不希望源参数的内容被修改
- 值传递会导致忽略实参的cv属性,这样对写函数重载有好处,如果有两个形参的类型一样,而实参传入时的cv属性不同,不至于导致重载匹配的失败
当然如果打算用值传递的话,拷贝开销就是避免不了的问题了。
#29
内置类型建议使用pass by value
#30
如果按值传参,那么在递归函数回溯时就无需手动对参数进行还原。而传引用的话,改变的参数值必须在回溯时手动还原,这很容易出错,这算一个实用型的小意义吧
#31
像这种需求, 引用就没有这么方便了.
class MyClass
{
public:
int m_a;
}
int fun( MyClass a)
{
a.m_a = 100;
return a.m_a;
}
想使用a, 但是又不想改变外部的a, 但又能在内部直接对a对象的现有数据进行操作. 这时就只能用传值了.
你传引用,或者常引用都不能办到.
当然, 你说我可以在函数内,再定义一个对象, 把引用的对象复制一遍, 愿意这样做, 那我也无话可说.
class MyClass
{
public:
int m_a;
}
int fun( MyClass a)
{
a.m_a = 100;
return a.m_a;
}
想使用a, 但是又不想改变外部的a, 但又能在内部直接对a对象的现有数据进行操作. 这时就只能用传值了.
你传引用,或者常引用都不能办到.
当然, 你说我可以在函数内,再定义一个对象, 把引用的对象复制一遍, 愿意这样做, 那我也无话可说.
#32
碰到数组引用就呵呵了
数组一样有引用形式(不是引用数组中某个元素,而是整个数组),而且恰好是数组不能整体的当作一个参数传给函数。你把他隐式转换成指针再传的话,长度信息将会丢失
#33
C++中引入了按 引用传参的机制,实际上就是对实参起了一个别名,达到直接控制实参的目的。与按 值传参的方法相比,避免了开辟实参副本的时空开销。还可以可以通过const对是否允许改变实参进行控制。
我想问问各位大神,这样看来“按引用传参”是不是可以完全取代“按值传参”了呢?如果真的这样。按值传参的机制还有什么存在的意义呢?本人小菜,求指点!
语法规则而已,传递引用实际还是传递一个指针,只是在函数中按照引用的规则使用传人的参数而已
#34
咋没人将整个互联网内容引用传参给一个函数呢?
#35
非引用类型的copy-initialization保证对象的复制或转移。如果只传引用,除去函数引用你还可能得自己维护对象的生存期——很多时候明显多此一举。对于C++,传递对象引用特别地强调调用者在乎并且想避免对象的复制初始化——通常是基于开销或者同一性考虑。如果目的不是修改对象(使用左值引用),对象自身没有共享的可变状态,复制开销可以接受,那么没理由使用引用传递;典型地如内建类型的整数。
撇开C++不讲,call by reference相对call by value在很多时候能让调用变得更加简洁——例如Y combinator可以省掉CBV形式的eta conversion。代价类似:变量没法和lexical scope绑定确定生存期。
科普:
http://en.wikipedia.org/wiki/Evaluation_strategy
撇开C++不讲,call by reference相对call by value在很多时候能让调用变得更加简洁——例如Y combinator可以省掉CBV形式的eta conversion。代价类似:变量没法和lexical scope绑定确定生存期。
科普:
http://en.wikipedia.org/wiki/Evaluation_strategy
#36
有很多同胞告诉我:引用传参实际还是传递一个指针,所以对于一些小字节的数据,没必要用“引用传参”。
可是我在网上看到这样的话:传递变量的指针。形参是指针变量,实参是一个变量的地址,调用函数时,形参(指针变量)指向实参变量单元。这种“虚实结合”的方法仍然是“值传递”方式,只是实参的值是变量的地址而已。通过形参指针变量访问主函数中的变量(i和j),并改变它们的值。(这样就能得到正确结果,但是在概念上却是兜了一个圈子,不那么直截了当。)
这段话,明确的指出:引用传参并非传递变量的指针。有没有大神出来,解释下。这两种传参方式又有什么区别呢?
可是我在网上看到这样的话:传递变量的指针。形参是指针变量,实参是一个变量的地址,调用函数时,形参(指针变量)指向实参变量单元。这种“虚实结合”的方法仍然是“值传递”方式,只是实参的值是变量的地址而已。通过形参指针变量访问主函数中的变量(i和j),并改变它们的值。(这样就能得到正确结果,但是在概念上却是兜了一个圈子,不那么直截了当。)
这段话,明确的指出:引用传参并非传递变量的指针。有没有大神出来,解释下。这两种传参方式又有什么区别呢?
#37
内置类型建议使用pass by value
说法好洋气
#38
传值有这么几个作用:
- 函数内部需要用到改变的传入参数,却不希望源参数的内容被修改
- 值传递会导致忽略实参的cv属性,这样对写函数重载有好处,如果有两个形参的类型一样,而实参传入时的cv属性不同,不至于导致重载匹配的失败
当然如果打算用值传递的话,拷贝开销就是避免不了的问题了。
我可以问:cv是什么吗?请原谅我的无知。
#39
传值有这么几个作用:
- 函数内部需要用到改变的传入参数,却不希望源参数的内容被修改
- 值传递会导致忽略实参的cv属性,这样对写函数重载有好处,如果有两个形参的类型一样,而实参传入时的cv属性不同,不至于导致重载匹配的失败
当然如果打算用值传递的话,拷贝开销就是避免不了的问题了。
我可以问:cv是什么吗?请原谅我的无知。
标准中规定必须有的目前只有const和volatile这两个(就是这个所谓的“cv”)。但是允许编译器 在此基础上再扩展一些(比如大部分机器上需要支持aligned属性),这些扩展的属性和const和volatile一起称作"cv属性"(而不是仅仅const和volatile这两个)
#40
有很多同胞告诉我:引用传参实际还是传递一个指针,所以对于一些小字节的数据,没必要用“引用传参”。
可是我在网上看到这样的话:传递变量的指针。形参是指针变量,实参是一个变量的地址,调用函数时,形参(指针变量)指向实参变量单元。这种“虚实结合”的方法仍然是“值传递”方式,只是实参的值是变量的地址而已。通过形参指针变量访问主函数中的变量(i和j),并改变它们的值。(这样就能得到正确结果,但是在概念上却是兜了一个圈子,不那么直截了当。)
这段话,明确的指出:引用传参并非传递变量的指针。有没有大神出来,解释下。这两种传参方式又有什么区别呢?
CBV和CBR本来就两回事。
只不过在需要保持恒定调用约定以保持公开的二进制兼容性,不进行程序变换为基础的优化的前提下,在实现意义上传递C++内建指针和传递C++内建引用类型的参数生成的代码效果类似。具体会怎么样随实现高兴,和C++本身做了什么(抽象机为基础的基本语义)已经无关了。
“实参的值是变量的地址”纯属扯淡,基本上就没搞清楚值有类型而地址不考虑类型的基本概念。
#41
传值有这么几个作用:
- 函数内部需要用到改变的传入参数,却不希望源参数的内容被修改
- 值传递会导致忽略实参的cv属性,这样对写函数重载有好处,如果有两个形参的类型一样,而实参传入时的cv属性不同,不至于导致重载匹配的失败
当然如果打算用值传递的话,拷贝开销就是避免不了的问题了。
我可以问:cv是什么吗?请原谅我的无知。
标准中规定必须有的目前只有const和volatile这两个(就是这个所谓的“cv”)。但是允许编译器 在此基础上再扩展一些(比如大部分机器上需要支持aligned属性),这些扩展的属性和const和volatile一起称作"cv属性"(而不是仅仅const和volatile这两个)
准确地说cv就只是指const和volatile这两个限定符(qualifier) 。其它语法地位相当的限定符不会称为cv。
同样是限定符的,在ISO C中还有restrict和_Atomic。
#42
内置类型还是传值效率高
#43
坐看各大牛人语录,哈哈!!长见识啊
#44
MARK一下,回去慢慢看。。
#45
看各位大神讨论,学习了
#46
看各位大神讨论,学习了
#47
听得我好乱,还有谁有想法。来说啊!
#48
内置类型建议使用pass by value
说法好洋气
这些术语还是原始的比较好。
#49
内置类型建议使用pass by value
说法好洋气
这些术语还是原始的比较好。