传值和传引用,返回引用等问题

1.宁以pass-by-reference-to-const替换pass-by-value
什么么说传值的方式对于一些情况不好,看个例子:
bool f(student s);
student p;
bool pisok=f§;

当我们传值时,调用端s是复制了p,那么,就需要调用一次student的copy构造函数和析构函数,并且,如果student继承自person的话,还得调用person的copy构造函数。那么这么多构造函数实现效率会很低。而pass-by-reference-to-const可以很好避免这个问题,因为它并没有创建一个新对象。而const的目的是为了防止客户改变传入参数。传值不用const因为客户只会改变传入参数的副本,没有关系。

另外,传值还会产生切割问题,如果一个派生类对象以传值方式传递并且视为基类对象,那么这会导致派生类自身的特殊性质无法copy生成。
而传递引用会解决这个问题,因为引用往往是以指针实现的,真正传递的是指针,而基类类型的指针是可以指向派生类对象的。这种指针对于子类的虚函数时可以调用的。

所以总结一下,如果对象时内置类型(如Int等),或者STL迭代器和函数对象,用传值方式比较好,其他的比如自己定义的类型用传引用方式比较好。

2、必须返回对象时,别妄想返回其引用
前面说了传递引用的一些好处,但是在一度追求传递引用时要注意,避免传递一些引用指向并不存在的对象。
为什么这么说呢?举个例子
const rational operator*(const rantional& lhs,(const rantional& rhs);
这是计算有理数乘积的函数,返回一个有理数对象。那么不可避免要传值方式返回一个结果对象,需要构造函数和析构函数。那么我们是否可以返回对象的引用呢?
首先,引用其实是代表某个既有对象的别名。所以,如果返回引用,我们必须先生成一个对象在函数乘法运行之前就存在(用来返回乘积)。这样的话,其实就需要构造函数了,已经和目标相悖了。更糟糕的是,
如果我们是生成一个local对象,比如
rational result(lhs.nrhs.h,lhs.drhs.d); n,d代表分母分子
我们知道局部对象是从栈中分配的,函数离开后就要销毁,这样的话,我们返回的引用指向的就是一个已经销毁的对象,这就是为什么说避免传递一些引用指向并不存在的对象。之后对返回的引用做任何操作都是未定义的行为。十分恐怖。
如果我们从堆中new一个对象,那么更糟糕,首先他也会有构造函数的代价。另外,new一定要delete,我们没有合理的办法返回引用背后隐藏的指针。比如w=xyz,这时候需要两次new和delete.
还可以想到其他办法避免构造函数的代价(比如局部静态对象),但是都不理想,与其这么绞尽脑汁想这些办法,不如好好生活,让编译器来降低传值的成本。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值