EffectiveC++读书笔记——item32(is-a原则)

1. public inheritance 的核心规则

在 C++ 的面向对象编程中,最重要的规则是:public inheritance 意味着 “is - a”。即当class Dclass B公开继承时,表明每个D类型的对象也是B类型的对象,但反之不成立。例如:

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

这表明每个学生都是人,但并非每个人都是学生。任何期望参数类型为Person(或pointer - to - Personreference - to - Person)的函数,都可以接受Student对象(或pointer - to - Studentreference - to - Student),如:

void eat(const Person& p); 
void study(const Student& s); 

Person p; 
Student s; 

eat(p); 
eat(s); 
study(s); 
// study(p);  // 错误,p不是Student

此规则仅适用于 public inheritance,private inheritance 和 protected inheritance 含义不同。

2. 违背 “is - a” 规则的案例分析

  • 鸟类案例:起初可能认为企鹅是鸟,鸟能飞,于是设计如下继承体系:
class Bird {
public:
    virtual void fly();  
  ...
};

class Penguin : public Bird {  
  ...
};

但这与事实不符,因为企鹅实际不能飞。更准确的设计应区分能飞和不能飞的鸟:

class Bird {
  ...  
};

class FlyingBird : public Bird {
public:
    virtual void fly();
  ...
};

class Penguin : public Bird {
  ...  
};

当然,对于不涉及飞行处理的应用程序,最初的设计可能也适用。另外,也有人认为可让企鹅重定义fly函数以产生运行时错误,但更好的方式是通过编译器阻止非法行为,如:

class Bird {
  ...  
};

class Penguin : public Bird {
  ...  
};

Penguin p;
// p.fly();  // 错误,编译器阻止该非法行为
  • 几何图形案例:从数学角度,正方形是矩形,但在 C++ 中,若SquareRectangle公开继承,可能出现问题。例如:
class Rectangle {
public:
    virtual void setHeight(int newHeight);
    virtual void setWidth(int newWidth);
    virtual int height() const;
    virtual int width() const;
  ...
};

void makeBigger(Rectangle& r) {
    int oldHeight = r.height();
    r.setWidth(r.width() + 10);
    assert(r.height() == oldHeight);
}

class Square : public Rectangle {... };

Square s;
assert(s.width() == s.height());
makeBigger(s);
assert(s.width() == s.height());

由于正方形宽高必须相等,而makeBigger函数对矩形宽的改变与正方形的特性冲突,这表明在此场景下,用 public inheritance 模拟正方形和矩形的关系是错误的,尽管编译器允许,但代码行为可能不正确。

3. 总结

public inheritance 意味着 “is - a”,适用于基类的所有特性也应适用于派生类,因为每个派生类对象都是基类对象。在设计时,要确保遵循此规则,避免因违反该规则导致设计错误。同时,除了 “is - a” 关系,类之间还存在 “has - a” 和 “is - implemented - in - terms - of” 等关系,需正确理解并模拟这些关系。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值