栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

Effective C++改善程序与设计的55个具体做法 6. 继承与面向对象设计

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Effective C++改善程序与设计的55个具体做法 6. 继承与面向对象设计

条款 32: 确定你的 public 继承塑模出 is-a 关系

"public 继承"意味 is-a。适用于 base classes 身上的每一件事情一定也适用于derived classes 身上,因为每一个 derived class 对象也都是一个 base class 对象。

个人理解:基类的函数适用于派生类的每一个函数。

条款 33: 避免遮掩继承而来的名称

derived classes 内的名称会遮掩 base classes 内的名称。在 public 继承下从来没有人希望如此。

为了让被遮掩的名称再见天日,可使用 using 声明式或转交函数( forwarding functions)。

个人理解:相同名称会有覆盖的问题,public 继承可以用using 声明, private函数可以使用转交函数。

条款 34: 区分接口继承和实现继承

接口继承和实现继承不同。在 public 继承之下, derived classes 总是继承 base class的接口。

pure virtual 函数只具体指定接口继承。

简朴的(非纯) impure virtual 函数具体指定接口继承及缺省实现继承。

non-virtual 函数具体指定接口继承以及强制性实现继承。

个人理解:接口继承只继承函数接口,实现继承继承接口和实现、并且又能够重写;

条款 35: 考虑 virtual 函数以外的其他选择

virtual 函数的替代方案包括 NVl 手法及 Strategy 设计模式的多种形式。 NVI 于法自身是一个特殊形式的 Template Method 设计模式.

将机能从成员函数移到 class 外部函数,带来的一个缺点是,非成员函数无法访问 class 的 non-public 成员。

std::function 对象的行为就像→般函数指针。这样的对象可接纳"与给定之目标签名式 (target signature) 兼容"的所有可调用物 (callable entities)。

个人理解:

使用NVI手法,他是用public non-virtual成员函数包裹较低访问性(private和protected)
的virtual函数;

将virtual函数替换成“函数指针成员变量”,这是strategy设计模式的一种表现形式;

****以tr1::function成员变量替换virtual函数,因而允许使用任何可调用物(callable entity)
搭配一个兼容与需求的签名式,这也是strategy设计模式的某种形式;

将继承体系内的virtual函数替换成另一个继承体系内的virtual函数。这是strategy设计模式的传统做法;

条款 36: 绝不重新定义继承而来的 non-virtual 函数

绝对不要重新定义继承而来的 non-virtual 函数

个人理解:继承类会覆盖基类中函数实现;

条款 37: 绝不重新定义继承而来的缺省参数值

绝对不要重新定义一个继承而来的缺省参数值,因为缺省参数值都是静态绑定,而virtual函数一一你唯一应该覆写的东西一一却是动态绑定。

个人理解:

class Shape{
public:
	enum ShapeColor {Red, Green, Blue};
	virtual void draw(ShapeColor color=Red) const = 0;
};

class Rectangle : public Shape{
public:
	virtual void draw(ShapeColor color=Green) const;//和父类的默认参数不同
}

Shape* pr = new Rectangle; // 注意此时pr的静态类型是Shape,但是他的动态类型是Rectangle
pr->draw(); //virtual函数是动态绑定,而缺省参数值是静态绑定,**所以会调用Red,而不是green**

class Rectangle : public Shape{
public:
	virtual void draw(ShapeColor color= Red) const; //可以更换为NVI的手法可以实现目的**
class Shape{
public:
	enum ShapeColor {Red, Green, Blue};
	void draw(ShapeColor color=Red) const {
		doDraw();
	}
private:
	virtual void doDraw(ShapeColor color) const = 0;
};

class Rectangle : public Shape{
public:
	virtual void doDraw(ShapeColor color) const;
}

条款 38: 通过复合塑模出 has-a 或"根据某物实现出”

复合( composition) 的意义和 public 继承完全不同。

在应用域 (application domain) ,复含意味 has -a (有一个)。在实现域(implementation domain) ,复合意味 is-implemented-in-terms-of(根据某物实现出)。

个人理解:

//应用领域:
class Address {...};
class PhoneNumber {...};
class Person {
	...
private:
	std::string name;
	Address address;
	PhoneNumber phone;
} 

//实现域:set并不是一个list,但是set可以has a list:
template
class Set{
public:
	void insert();
	//.......
private:
	std::list rep;
}

条款 39: 明智而审慎地使用 private 继承

Private 继承意味 is-implemented-in-terms of (根据某物实现出)。它通常比复合(composition) 的级别低。但是当 derived class 需要访问 protected base class 的成员,或需要重新定义继承而来的virtual 函数时,这么设计是合理的。

和复合( composition) 不同, private 继承可以造成 empty base 最优化。这对致力于"对象尺寸最小化"的程序库开发者而言,可能很重要。

个人理解:如果D以private形式继承B,private继承意味着只有实现部分被继承,而没有其他含义。尽可能的使用复合,必要时才使用private(总结中提到的两种情况)

条款 40: 明智而审慎地使用多重继承

多重继承比单一继承复杂。它可能导致新的歧义性,以及对 virtual 继承的需要。

virtual 继承会增加大小、速度、初始化(及赋值)复杂度等等成本。如果 virtual base classes 不带任何数据,将是最具实用价值的情况。

多重继承的确有正当用途。其中一个情节涉及"public 继承某个 Interface class" 和 "private 继承某个协助实现的class" 的两相组合。

个人理解:多重继承基类对象存在多个

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1018881.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号