Ch18: Virtual

中文(简体)

What This Chapter Is For

This chapter is about new, delete, ::std::unique_ptr, virtual and RTTI. These are the four most overused features in C++, and the four that C++ tutorials introduce first. We introduce them here for one reason only: you have to read legacy code. Almost every C++ codebase you will be paid to touch is built out of them.

We do not use them in new code, and this chapter says exactly why, with measurements. The short version:

Legacy feature What it actually costs What to write instead
new / delete Manual lifetime, invisible failure path, failure arrives as the legacy ::std::bad_alloc exception An owner type with a destructor; containers that own their storage
::std::unique_ptr<T> Heap round trip per object, plus a pointer that does not say what T means at the call site A value type; type erasure when you really need one type for many representations
virtual A pointer in every object, a table per class, every virtual function emitted whether called or not, __cxa_pure_virtual, RTTI, a non-portable ABI Template dispatch, or a function-pointer table that you own
typeid / dynamic_cast Type-info objects per class, mangled names, a runtime search per cast Nothing: with type erasure there is nothing to cast to
class-level operator new Allocates policy hidden inside a type, matched-delete traps A factory function or an arena you pass in (Ch18.7)
Qt / MFC style GUI Deep virtual hierarchies, new everywhere, one framework ABI for your whole program A web front end in front of a C++ service (Ch21: PWAs)

The rules in $HOME/libraries/Portable-Cpp-Guideline are the source of this position: avoid new, avoid ::std::unique_ptr, use type erasure over virtual functions for polymorphism, and prefer a C-style pseudo v-table singleton over the C++ v-table.

Why We Are Against Them

One paragraph each, so the rest of the chapter has something to prove:

The Contents of This Chapter

How to Read This Chapter

Read 18.1 to 18.5 as recognition training: you are learning to see these constructs in other people's code and to know what each one is buying and costing. Read 18.6 as the chapter you actually use. Read 18.7 only on the day you must allocate through a type. Read 18.8 before you accept a job that says "Qt developer".

Everything here is a rule about your code. You will still have to call libraries that use virtual; that is fine, and the fast_io device layer does it too. What you must not do is build new abstractions on top of it.