32 Make sure public inheritance models "is-a"

"is-a":
Foo is-a Bar :

class Foo : public Bar

"has-a"
Foo has-a Bar

class Foo
{
  private:
    Bar b;
};

If you write that class D publicly inherits from class B(Base), you are telling C++ compilers that every object of type D is also an object of type B. You are saying that B represents a more general concept than D, that D represents a more specialized concept than B. Anywhere an object of type B can be used, an object of type D can be used as well. It is actually a is-a model.

For example, we know that every student is a person, but not every person is a student. Within the realm of C++, any function that expects an argument of type Person will also take a Student object :

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

Person p;
Student s;

eat(p);
eat(s);

study(s);   
study(p);  // error!

This is true only for public inheritance. C++ will behave what we said before only if Student is publicly derived from Person, Private inheritance means something entirely different, and protected inheritance is something whose meaning eludes me to this day.

The equivalence of public inheritance and is-a sounds simple, but sometimes your intuition can mislead you. For example, it is a fact that a penguin is a bird, and it is a fact that birds can fly. If we natively try to express this in C++, our effort yields :

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

Suddenly we are in trouble, because this hierarchy says that penguins can fly, which we know is not true. What happened?

This is the problem that means "All birds can fly, penguins are birds, penguins can't fly !" . That is to redefine the fly function for penguin so that it generates a runtime error :

void error(const std::string& msg);
class Penguin : public Bird
{
public:
  virtual void fly() {error(",,,");}
};

Actually, what is this program saying is that penguins try to fly , but it can't. We know that it says this in the runtime, however, what we want is that we get a message that penguins can't fly, which means that we should get the message while compiling.

To express the constraint, "Penguins can't fly -- period", you make sure that no such function is defined for Penguin objects:

class Bird{
...  // no fly function is declared
};

class Penguin : public Bird{
... // no fly function is declared
};

It you now try to make a penguin fly, compilers will reprimand you for your transgression :

Penguin p;
p.fly(); // error!

Conclusion

  • Public inheritance means "is-a." Everything that applies to base classes must also apply to derived classes, because every derived class object is a base class object.
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容