天天看点

[GeekBand ] 利用 pass by reference -to -const 编写高效规范的 c++代码

本文参考资料 :  GeekBand 侯捷老师,学习笔记

                       Effective C ++ 侯捷译 条款20

                       开发环境采用:VS2013版本

首先:分析值传递的缺点 (一)

class Person{
public:
    Person();
    virtual ~Person();
private:
    std::string name;
    std::stringi address;
};

class Student: public Persion{
public:
    Student();
    ~Student();
private:
    std::string schoolName;
    std::string schoolAddress;
};
      

  函数调用部分:

bool validateStudent(Student s);
Student plato;
bool platoIsOk = validateStudent(plato);
      

  

通过以上代码,分析得:

1、基类Student的构造函数调用,以plato 为蓝本为s初始化;结束时调用一次析构函数。

     基类Student中有两个String对象,此时又有两次构造函数和析构函数。

     基类Student共有三次构造、三次析构

2、每次构造Student对象必须构造一次Person对象。因为Student继承自Person对象。

     同理,Person也有三次构造、三次析构。

推论:这种按值传参的方式,效率有点低啊。同时如果采用按引用传递,那么没有任何构造函数或析构函数被调用,因为没有任何对象被创建

然后:分析值传递的缺点 (二)

Class Window
{

public:
std::string name() const;
virtual void display() const;    
}
Class WindowWithScrollBars:public Window
{

public:
virtual void display() const; 

}
      

  

观察代码得知:

     1、子类WindowWithScrollBars继承自基类Windows

     2、基类、子类中均有函数 display,这里简单的把基类的display记为,dispaly_1.子类的记录为,display_2

void printNaAndDisplay(Window w)
{

std::cout<<w.name();
w.display();

}
      

  

而此时

WindowWithScrollBars wwsb;
printNameAndDisplay(wwsb);
      

  这时创建了子类对象wwsb,看上去应该调用子类的dispay_2才对,而实际上因为void printNameAndDisplay(Window w),是按值传递的。

无论传递过来的数值是什么,夸张点的、比如整形、字符型等等。都会自动的转换为Window类型,因为传递过来的仅仅是数值!!!

所以,这里调用的是基类的display,所以此程序无法满足程序员最开始的设想!

解决这个问题,同样采用引用传递即可!

传进来是什么类型,w就是那种类型

三、再说说,为什么采用const这个参数进行限定

按引用传递后,在函数内部会改变传过来的数值。而改动函数的返回值从来就不是合法的。所以我们加个限定词 const,这样就解决这个问题了。

[GeekBand ] 利用 pass by reference -to -const 编写高效规范的 c++代码