effective cpp小结条款21~40

条款21

在栈上创建对象

const Rational& operartor* (const Rational& lhs, const Rational& rhs) {
	Rational result(lhs.n * rhs.n, lhs.d * rhs.d);
	return result;//错误代码!
}

result是个local对象,在函数退出前就被销毁了

在堆上创建对象

const Rational& operartor* (const Rational& lhs, const Rational& rhs) {
	Rational * result = new Rational(lhs.n * rhs.n, lhs.d * rhs.d);//更糟糕的代码
	return result;
}
Rational w, x, y, z;
w = x * y * z;

这一句调用了两次operator*,因为使用了两次new,也就需要两次delete。但却没有合理的方法让operator* 使用者进行那些delete调用,因为没有合理的办法让他们取得operator*返回的引用背后隐藏的那个指针。将会导致资源泄漏。

让operator*返回的引用指向一个被定义在函数内部的static对象

const Rational& operartor* (const Rational& lhs, const Rational& rhs) {
	static Rational result;
	result = ...;
	return result;
}

//当执行下面的语句
bool operator==(const Rational& lhs, const Rational& rhs);
Rational a, b, c, d;
if ((a * b) == (c * d)) {
	//...			//总是会执行这一局
}
else {
	//...
}

两次operator* 调用的确各自改变了static Rational对象值,但是由于他们返回的都是reference, 因此调用端看到的永远是static Rational对象的“现值”。

总结:

  • 别返回对象的引用

条款22

将成员变量声明为private,就是隐藏成员变量,也就是封装他们,只有成员函数可以改变他们
public意味着不封装,不封装意味着不可改变,特别是对被广泛使用的classes而言。
protected成员变量就像public成员变量一样缺乏封装性。

条款23

宁以non-member、non-friend替换member函数

条款27

class Window { 
public: 
    virtual void onResize() {...} 
}; 
class SpecialWinddow : public Window { 
public: 
    virtual void onResize() { 
       static_cast<Window>(*this).onResize();//将*this转换成Window,然后调用其onResize;这样不行! 
    } 
};

这里会发生什么问题呢?static_cast(*this)这个转型动作并不是如你想象的那样得到当前对象的基类对象部分,其实编译器为你产生了的是当前对象的基类部分的副本

条款27参考

条款28,29

避免返回handles(包括reference、指针、迭代器)指向对象内部。遵守这个条款可增加封装性,帮助const成员函数的行为像个const,并将发生“虚吊号码牌”(dangling handles)的可能性降至最低。

条款28,29参考

条款30,31

inline只是对编译器的一个申请,不是强制命令
条款30,31参考

条款32

public inheritance(公有继承)意味“is-a”的关系。在进行面向对象类设计时,需要明确继承之前是否是"is-a"关系,以决定derived类与base类设计的合理性。

书中有2个例子:鸟和企鹅关于fly()函数的讨论,以及矩形和正方形关于长宽的讨论
结论:适用于base classes身上的每一件事一定也适用于derived身上,因为每一个derived对象也是一个base class 对象。(企鹅不会飞,而鸟类一般会飞,矩形长宽可以不一样正方形必须一样,所以必须采取措施解决公有继承带来的问题)

条款32参考

条款34

  1. pure virtual函数的目的是为了让derived classes只继承函数接口
  2. impure virtual函数会提供一份实现代码,derived class可能覆盖它
  3. non-virtual函数具体指定接口继承以及强制性实现继承
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值