menu

hjk41的日志

Avatar

Effective C++35: Make sure public inheritance models "isa"

Is penguin a bird? You may say yes, but this is not exactly the case in the realm of C++.


class Bird {
public:
  virtual void fly();               // birds can fly
  ...
};
class Penguin:public Bird {      // penguins are birds
  ...
};


We all know that bird can fly while penguins can't. But with this code, one surely can call Penguin::fly(). Now, tell me, is penguin a bird?
"Not all birds can fly", you may argue, "We are just the victims of an imprecise language."
Okay, let's take another example. Consider the following code:

class Rectangle {
public:
  virtual void setHeight(int newHeight);
  virtual void setWidth(int newWidth);
  virtual int height() const;          // return current
  virtual int width() const;           // values
  ...
};
void makeBigger(Rectangle& r)          // function to
{                                      // increase r's area
  int oldHeight = r.height();
  r.setWidth(r.width() + 10);          // add 10 to r's width
  assert(r.height() == oldHeight);     // assert that r's
}                                      // height is unchanged

class Square: public Rectangle { ... };
Square s;
...
assert(s.width() == s.height());      // this must be true
                                      // for all squares
makeBigger(s);                        // by inheritance, s
                                      // isa Rectangle, so
                                      // we can increase its
                                      // area
assert(s.width() == s.height());      // this must still be
                                      // true for all squares


Suqares are rectangles. And the width of a rectangle can be changed while the height stands unchanged. However, we can't perform the same operation on a square, thus deriving Square from Rectangle is not proper here.

A "isa" B means one thing in the real world, but another in the world of C++. In C++, A "isa" B means A can be used everwhere B can be used. And this is the most important thing of public inheritance.

评论已关闭