Skip to content

Concept Checks — Answers

Back to the questions


CC1. Preprocessing, compilation, linking.

CC2. Linking. The declaration satisfied the compiler; the definition is what the linker needs.

CC3. Encapsulation, inheritance, polymorphism, abstraction.

CC4. One source file after preprocessing, together with everything it #included — the unit the compiler turns into one object file.

CC5. A class is a type (a description); an object is one instance of it with its own data.

CC6. A statement that must be true of an object for its whole lifetime, enforced by the operations that change it.

CC7. class members are private by default; struct members are public by default.

CC8. That calling it will not modify the object — so it may be called on a const object or through a const reference.

CC9. The object the member function was called on.

CC10. Declaration order — the order the members appear in the class, not the order in the initialiser list. (Hence GCC's -Wreorder.)

CC11. Automatically, when the object's lifetime ends: at scope exit, on delete, or during stack unwinding.

CC12. A constructor that calls another constructor of the same class from its initialiser list, so the initialisation logic lives in one place.

CC13. None. If the constructor throws, no complete object was built, so its destructor does not run (the already-constructed members' destructors do).

CC14. operator=. operator+ may be either (often free); operator<< must be a free function.

CC15. A strict weak ordering — in particular a < a must be false — provided by operator<.

CC16. The class itself, shared by every instance (one copy for the class, not one per object).

CC17. The derived type must be usable everywhere the base is expected (an "is-a"), and the base must describe what the derived is. Otherwise use composition.

CC18. Bases are constructed before derived parts; destruction runs in the reverse order (derived before base).

CC19. Copying a derived object into a base value, which keeps only the base part. Store pointers or references — a container of unique_ptr<Base> — to avoid it.

CC20. It is a compile-time check: it makes the compiler verify that the function really overrides a virtual base function. It changes nothing at run time.

CC21. A virtual function has a body and derived classes may replace it; a pure virtual (= 0) function has no body, so the class is abstract and cannot be instantiated until a derived class implements it.

CC22. Whenever the class is meant to be deleted through a base pointer (i.e. whenever it has other virtual functions and is used polymorphically), the base destructor must be virtual.

CC23. In composition the part's lifetime is bounded by the whole's (it dies with it); in aggregation the part exists independently and outlives the whole.

CC24. To be responsible for its lifetime: the owned object is destroyed with the owner, and the owner must not outlive it (nor it the owner).

CC25. If a class needs any one of the destructor, copy constructor or copy assignment operator, it almost certainly needs all three. It does not apply when the class owns no resource — then the Rule of Zero applies instead.

CC26. If a class's members manage their own resources (e.g. std::string, std::vector), the class should write none of the five special members; the compiler-generated ones are correct.

CC27. Valid but unspecified: its invariants hold and it can be destroyed or assigned to, but its value is not defined and must not be relied on.

CC28. Resource Acquisition Is Initialisation: acquire a resource in a constructor and release it in the destructor, so its lifetime is the object's lifetime.

CC29. std::unique_ptr, transferred with std::move. Copying it is a compile error.

CC30. On reallocation, std::vector only moves elements when the move cannot throw (noexcept); otherwise it copies them, to keep its strong exception guarantee.

CC31. Two objects holding shared_ptrs to each other keep each other alive forever. Replacing one direction with std::weak_ptr breaks the cycle.

CC32. The compiler must see the definition where the template is used, to instantiate it; a declaration alone leaves it unable to generate the code.

CC33. Basic, strong, nothrow.

CC34. O(1) average lookup: std::unordered_map (or unordered_set). Sorted keys: std::map (or std::set).

CC35. erase (and insert on some containers) invalidates iterators. erase returns an iterator to the next element.

CC36. Single Responsibility, Open/Closed, Liskov Substitution, Interface Segregation, Dependency Inversion.


Scoring. 36 questions: count a correct short answer as a point. Above 90% is ready for advanced work; see Marking Yourself.