#include #include #include #include struct Trace { std::array values{}; std::size_t used = 0; void add(int value) noexcept { assert(used < values.size()); values[used++] = value; } }; class Base { protected: Trace& trace; void sample() { trace.add(kind()); } public: explicit Base(Trace& t) : trace(t) { sample(); } virtual ~Base() { sample(); } virtual int kind() const noexcept { return 1; } }; class Derived final : public Base { public: explicit Derived(Trace& t) : Base(t) { sample(); } ~Derived() override { sample(); } int kind() const noexcept override { return 2; } }; int main() { Trace trace; { Derived object(trace); const Base& view = object; trace.add(view.kind()); } const std::array expected{{1, 2, 2, 2, 1}}; assert(trace.used == expected.size()); assert(trace.values == expected); for (std::size_t i = 0; i < trace.used; ++i) { if (i != 0) std::cout << ' '; std::cout << trace.values[i]; } std::cout << '\n'; }