Ch16: Inheritance: Sharing a Layout, Not a Dispatcher

中文(简体)

1. What This Chapter Is, and What It Is Not

Inheritance in C++ is one feature with two halves. The first half is a layout and access mechanism: a derived class contains a base-class subobject at the front, inherits its members, and may be used wherever the base is expected. The second half is dynamic dispatch through virtual functions.

This chapter is the first half only. Every example here is resolved at compile time by the compiler; none of them needs a vtable, and the word virtual appears on exactly one page — Ch16.7 — where the override keyword is introduced, because that keyword has no meaning without it. Chapter 18 is the dispatch chapter.

The reason to split them is that the two halves are used for different things and cost different things. Inheriting a layout is free, common, and useful on its own: a labeled_point really is a point with a name attached. Inheriting an interface costs a pointer per object and an indirect call per operation, and is Ch15.10's alternative. Mixing the two discussions is how people end up believing that inheritance is polymorphism.

2. The One-Sentence Summary of Each Idea

Idea One sentence Subchapter
base subobject A derived object contains its base object, first, as a part of itself. Ch16.1
construction order Bases, then members, then the body; destroyed in exactly the reverse. Ch16.2
access specifiers public inheritance means is-a; private inheritance adopts an implementation and publishes chosen operations with using. Ch16.3
five rules, derived Each of the five members does the base subobject too — and forgetting the base in assignment compiles. Ch16.4
conversion and slicing A derived object is a base object, so it can be bound to a base reference — and copied into a base value, which loses the rest. Ch16.5
name hiding A name declared in the derived class hides every base-class overload of that name, unless you say using. Ch16.6
override An annotation that makes the compiler prove the derived function really does override a base one. Ch16.7
composition A member is a better answer than a base class whenever is-a is not literally true. Ch16.8

3. The Running Example

One small hierarchy runs through the chapter: a machine made of a base part and an engine.


class machine_part
{
protected:
	::std::int_least32_t serial_{};

public:
	::std::int_least32_t serial() const noexcept { return serial_; }
};

class machine : public machine_part
{
protected:
	::std::int_least32_t power_{};

public:
	::std::int_least32_t power() const noexcept { return power_; }
};

machine is-a machine_part: every machine has a serial number, and a machine_part& can be bound to any machine. Nothing here is virtual, and everything is decided while compiling.

4. Conventions Used in This Chapter

5. What You Should Already Know

6. Contents