Effective C++ Item 32 确定你的 public 继承塑模出 is-a 关系

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie

经验:"public继承"意味 is-a。适用于 base classes 身上的每一件事情一定也适用于 derived classes 身上,

因为每一个 derived classes 身上,因为每一个 derived class 对象也都是一个 base class 对象。

示例:

class Person {...};
class Student: public Person {...};

void eat(const Person &p); //任何人都会吃
void study(const Student &s); //只有学生才到校学习
Person p;  //p 是人
Student s; //s 是学生
eat(p);    //ok p是人
eat(s);    //ok s是学生,但学生也是(is-a)人
study(s);  //ok s是学生
study(p);  //error p不是学生

解析:上面的例子只对 public继承才成立。 对private, protected 继承不成立。

public 继承的问题示例

1.企鹅是一种鸟,鸟会飞,但企鹅不会飞

class Bird{
public:
	virtual void fly(); //鸟可以飞
};
class Penguin: public Bird{ //企鹅是一种鸟
};

如果你的软件系统现在以及未来不需要区别会不会飞的鸟的话,

这样的“双classes继承体系”就可以了,否则可以进行如下更改

class Bird{
	//... -->没有声明 fly 函数,鸟不一定会飞
};
class FlyingBird: public Bird{
public:
	virtual void fly();
};

class Penguin: public Bird{
	//... -->没有声明 fly 函数
};

2.class Square 应该以 public 形式继承 class Rectangle 吗?

class Rectangle{
	virtual void setHeight(int newHeight);
	virtual void setWidth(int newWidth);
	virtual int height() const; //返回当前值
	virtual int width() const;
	//...
};

void makeBigger(Rectangle &r) //这个函数用以增加 r 的面积
{
	int oldHeight = r.height();
	r.setWidth(r.width() + 10); //为 r 的宽度加10
	assert(r.height() == oldHeight); //判断 r 的高度是否未曾改变
}

class Square: public Rectangle {...};
Square s;
//...
assert(s.width() == s.height()); //这对所有正方形一定为真
makeBigger(s); //由于s 是一种(is-a)矩形,所以我们增加其面积。
assert(s.width() == s.height()); //对所有正方形应该仍然为真 --> 但事实上由于上一步 makeBigger函数的作用,这里已经不为真了

Effective C++ Item 32 确定你的 public 继承塑模出 is-a 关系,布布扣,bubuko.com

时间: 2024-08-03 19:24:58

Effective C++ Item 32 确定你的 public 继承塑模出 is-a 关系的相关文章

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

1. public继承意味着"is-a"(是一个)关系,是接口的完全继承(不一定是接口实现的完全继承).例如B继承自A,如果采用public继承,那么意味着B是A的一种,因此A可以进行的操作B同样也可以进行(尽管实现可能不同). 2. public继承的is-a含义(基类可以进行的操作派生类同样可以进行)与现实生活中的is-a含义可能有些许不同.例如,在生活中,正方形无疑是矩形的一种,因此可以认为是is-a关系;然而如果用public继承的is-a含义来解释,正方形可能就不可以publ

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

(一) public继承意味着"is-a"关系.它的意思是:如果B以public形式继承自A,那么B类型对象肯定是一个A对象,反之不成立.A是B的一种抽象,B是A的特例.任何使用A的地方,都能使用B. (二) public继承意味着"is a"(是一种)关系: (1)任何一个继承类对象也是一个基类对象: (2)任何可以出现基类对象的地方也可以出现一个继承类对象(例如函数的实参): (3)任何一个可以在基类对象上所做的操作,同样也可以在派生类上操作(结果可能是设计者想

《Effective C++》之条款32:确定你的public继承塑模出is-a关系

<Effective C++> 条款32:确定你的public继承塑模出is-a关系 Public inheritance(公开继承)意味"is-a"的关系. 例子如下: class Person{ ... }; class Student : public Person{ ... }; void eat(const Person& p);//任何人都会吃 void study(const Student& s);//只有学生才到校学习 Person p;/

[Effective C++ --032]确定你的public继承塑模出is-a

这一章都在讲述继承的关系.可以举个例子说明: 父类是水果,子类是苹果,苹果是一种(is-a)水果,但是水果不一定就是苹果. is-a并不是唯一存在classes之间的关系.另两个常见的关系是has-a(有一个)和is-implemented-in-term-of(根据某物实现出). 这些关系将在后面一一讲述. ◆总结 1.“public继承”意味着is-a.适用于base classes身上的每一件事情一定也适用于derived classes身上,以为每一个derived class对象也都是

Effective C++ Item 38 通过复合塑模出 has-a 或 is-implemented-in-terms-of

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:在应用域,复合意味着 has-a. 在实现域,复合意味着 is-implemented-in-terms-of 示例: template<typename T> //将list应用于 Set.错误做法 class Set: public std::list<T> {...}; 解析: public 继承表示 is-a,即如果D是一种B,对B为真的每一件事,对D也应该为真

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

(一) public继承是"is-a"的关系,而复合有"has-a"或"根据某物实现出(is-implemented-in-terms-of)"的意思--当复合发生在应用域内的对象之间,表现出has-a关系:当它发生于实现域内则是表示"根据某物实现出"的关系. 应用域部分,相当于你塑造的世界中的某些事物,例如人,汽车等. 后者的对象则是实现细节人工产品(这产品现实世界中是没有的),像什么mutex,list,container

读书笔记 effective c++ Item 32 确保public继承建立“is-a”模型

1. 何为public继承的”is-a”关系 在C++面向对象准则中最重要的准则是:public继承意味着“is-a”.记住这个准则. 如果你实现一个类D(derived)public继承自类B(base),你在告诉c++编译器(也在告诉代码阅读者),每个类型D的对象也是一个类型B的对象,反过来说是不对的.你正在诉说B比D表示了一个更为一般的概念,而D比B表现了一个更为特殊的概念.你在主张:任何可以使用类型B的地方,也能使用类型D,因为每个类型D的对象都是类型B的对象:反过来却不对,也就是可以使

Effective C++ 条款38 通过复合塑模出has-a或&quot;根据某物实现出&quot;

1. public继承体现is-a关系,要求接口的完全继承,而复合体现has-a或"根据某物实现出"的关系. 当复合发生在应用域(世界中的某些事物,如人,汽车,一张剪辑视频画面等)内的对象之间,表现出has-a关系,当发生在实现域(细节上的人工制品,如缓冲区,互斥器,查找树等)内,表现出is-implementation-in-terms-of(根据某物实现出)的关系. 2. 对于is-implementation-in-terms-of,例如基于list实现set(当空间比时间更重要

Effective JavaScript Item 32 绝不要修改__proto__

本系列作为Effective JavaScript的读书笔记. 和Object.getPrototypeOf相比,__proto__的特殊之处还体现在它能够修改一个对象的原型继承链.因为它是一个属性,除了执行获取它的操作外,还能够对它进行设置. 但是,绝不要修改__proto__.原因如下: 首先,最显而易见的原因就是便携性.因为不是所有的JavaScript执行环境都支持这一属性,所以使用了__proto__之后,代码就不能在那些不支持__proto__的环境中运行了. 其次,是性能上的考虑.