Prior to this answer, the idea with the factory put forward @gbg in the comments, so the palm belongs to him.
The correct approach in this case is this: hide the constructor and construct the objects through the factory. In the constructor, you have too little control, but with the factory you just get full control and scope for the further arbitrary complication of the program logic.
Example:
#include <iostream> #include <vector> #include <memory> using namespace std; class Base { friend class Factory; protected: Base() { cout << "Base constructed" << endl; } }; class Derived : public Base { friend class Factory; protected: Derived() { cout << "Derived constructed" << endl; } }; vector<shared_ptr<Base>> all_base_pointers; class Factory { public: static shared_ptr<Base> Construct() { static int alloc_no = 0; if (alloc_no++ % 2 == 0) return ConstructBase(); else return ConstructDerived(); } private: static shared_ptr<Base> ConstructBase() { shared_ptr<Base> p(new Base()); all_base_pointers.push_back(p); return p; } static shared_ptr<Base> ConstructDerived() { shared_ptr<Base> p(new Derived()); return p; } }; int main() { auto p1 = Factory::Construct(), p2 = Factory::Construct(), p3 = Factory::Construct(); cout << "constructed " << all_base_pointers.size() << " base instances" << endl; return 0; }
The output of the program:
Base constructed
Base constructed
Derived constructed
Base constructed
constructed 2 base instances