Effective C++ 读书笔记(20)

条款20:宁以pass-by-reference-to-const替换pass-by-value

考虑下面的例子:

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

class Student:public People{
public:
	Studenet();
	~Student();
	...
private:
	std::string schoolName;
	std::string shoolAddress;
};
考虑下面的调用:
bool validateStudent(Student s);
Student plato;
bool platoIsOk = validateStudent(plato);

在函数validateStudent函数调用的时候会发生什么事情?首先会调用Student的copy构造函数从plato copy构造对象s,在

函数validateStudent函数执行结束后,调用对象s的析构函数,这样总共调用了一次copy 构造函数和一次析构函数,但是在Student

类内部,有两个string成员对象,因此在Student构造函数的时候也会调用string类的两个构造函数,相应结束的时候也会调用string

的析构函数,又因为Student类继承子People,因此Student类的构造会引起People类对象的构造,对应的People对象两个string对象

的构造和对应的析构函数,这样一个函数的执行就涉及到了六次的构造函数和六次的析构函数,虽然调用时正确的,但是调用的效

率是太低了,我们可以通过pass-by-reference-to-const来调用,

bool validateStudent(const Student& s);

通过引用的调用可以防止对应的构造函数与析构函数的调用,const关键字主要是用来说明实参的对象是不能改变的,在

pass-by-value的调用方式中,实参的对象也是不能改变的,改变的是复制的临时对象!在函数返回的对象也是有相似的情况!

在pass-by-value还可能造成一种对象切割的情况,例如:

class Window{
public:
	...
	std::string name() const;
	virtual void display() const;
};

class WindowWithScrollBars:public Window{
public:
	...
	virtual void display() const;
	....
};

void printNameAndDisplay(Window w){
	std::cout << w.name()<<endl;
	w.display();
}
WindowWithScrollBars wwsb;
printNameAndDisplay(wwsb);

在上面的这种情况下,当wwsb传递给函数的参数w时,发生的是pass-by-value,此时调用的Window的copy构造函数,因

此,copy 构造函数构造的对象是Window类型的,不管实参类型是Window类型还是Window的子类型,这种情况叫对象的切割,对应

的如果我们将printNameAndDisply函数的参数修改为const Window& w,此时我们就可以在函数内部调用到子类的函数,这就是多态的

应用!需要注意!

在C++中并不是所有的对象都是要以pass-by-reference-to-const的形式,对于内置的类型和stl中的迭代器类型和函数对象

还是要采用pass-by-value的形式!


请注意:

  • 尽量以pass-by-reference-to-const来替换pass-by-value,前者不仅高效还能防止对象的切割问题
  • 对于内置类型和STL中的迭代器和函数对象还是要采用pass-by-value的形式比较高效



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值