Effective C++ rule 20.传参与传引用
来源:互联网 发布:数据采集方法 编辑:程序博客网 时间:2024/06/16 14:01
前言
Rule 20 阐述了我们在设置函数的形参时,尽量以pass by reference const 的形式,少用pass by value.主要基于效率和行为考虑的。
代码讲解
#include <stdio.h>#include <iostream>#include <string>using namespace std;class Person{public: string name;public: Person() { } virtual ~Person() { }public: virtual void say() const { cout << "Person:I am " << name; }};class Student :public Person{public: Student() :Person() { } ~Student() { }public: virtual void say() const { cout << "Student: I am " << name; }};void Sayv(Person p){ p.say();}void Sayr(const Person& p){ p.say();}int main(){ Student stu; Sayv(stu); Sayr(stu); return 0;}
1.我们来看调用Sayv与Sayr的开销: Sayv(Person p) 传入的时候需要调用Person的复制构造函数,在Sayv()结束的时候,需要调用Person的析构函数。Sayr(Person &p)没上面的步骤。
2.再看两个函数输出什么:
Sayv()调用的是Person的say()函数。而Sayr()调用的Student类的say()函数。Sayr(Person &p)其实就是使用了多态性来调用say()函数。
Sayv()因为是pass by value.导致stu被切割成只剩下基类Person的东西了。
为什么内置类型一般使用pass by value会更高效安全
文中还提到
我们编程验证一下:
int fv(int i){ return i*i;}int fr(const int &i){ return i*i;}int main(){ int x = 5; int y = fv(x); int z = fr(x); return 0;}
汇编代码:
60: int x = 5;010364FF mov dword ptr [x],5 把5存入x对应的内存中 61: int y = fv(x);01036506 mov eax,dword ptr [x] 取x内存中存储的值到eax01036509 push eax 传入eax0103650A call fv (010312B2h) 0103650F add esp,4 01036512 mov dword ptr [y],eax 62: int z = fr(x);01036515 lea eax,[x] 取x变量的有效地址到eax,就是传入x的地址进去。01036518 push eax 传入eax.01036519 call fr (010314BFh) 0103651E add esp,4 01036521 mov dword ptr [z],eax
其实对于内置类型(包括指针),传参数还是传引用效率上是差不多的,因为两个都要访问内存若干次。但是传参数的版本可以在不加const的情况下保证函数内部的操作不会影响到原来的变量X。
另外!
严格来说,传参效率还要低一些,因为它需要先取x的地址,然后将x的地址传到MAR寄存器,再从地址总线定位到内存单位,通过数据总线拿回X的值;而传引用的话只需要取x的地址,没有接下来访存的操作。
总结:
- 一般情况下,pass by reference const会比pass by value 少了很多复制构造函数和析构函数的调用,从这个角度来看pass by reference const 是很受推崇的
- pass by reference const利用多态性,可以避免pass by value对子类进行切割的问题。我们一般不想看到子类被切割了,但是也不排除某些场合下 我们就需要这个效果。
- pass by reference const的函数其实还有一个不太好的问题就是:因为传入的是一个常引用,导致在函数内部只能调用对象的const方法!比如上面的例子中 say()就需要是const函数。当然这或许也不是什么问题,在这个规定下,开发人员开发出来的类将更加规范,严格遵循const 对象只能调用const方法来保证对象的一致性。不过,个人还是更喜欢没有带const的pass by reference ,哈哈哈
阅读全文
1 0
- Effective C++ rule 20.传参与传引用
- 引用传参与指针传参
- Effective C++,Rule 3,使用const
- Effective c++:引用计数
- JAVA学习总结之值传参与引用传参
- Java实参和形参与传值和传引用
- Effective C++,rule 4,确保对象使用前被初始化
- more effective c++--引用计数
- C rule
- mui 传参与接收
- MyBatis传参与parameterType
- Effective C# Rule number 1
- More Effective C++:通过引用捕获异常
- More Effective C++:通过引用捕获异常
- 多用引用,而非传值 (Effective C++_20)
- C# 值类型传参与引用类型传参 在多线程调用时的区别
- 关于C++对函数传参与函数返回值进行引用传递的详解
- java按值传参与按引用传参_旺旺老师Java学习解决方案_第一季
- Pointers on C——7 Functions.10
- LintCode 落单的数 ⅡⅢ
- [svc]ansible知识点
- MyBatis获取插入记录的自增长字段值
- 集成开发环境-大数据开发平台的门户
- Effective C++ rule 20.传参与传引用
- Pointers on C——8 Arrays.1
- JDK 8 中的 Streams API 详解
- Dubbo框架
- Pointers on C——8 Arrays.2
- Shell脚本编程
- Android 设计模式
- Pointers on C——8 Arrays.3
- akka集群实战