How to find out in the constructor of a base class, is an object of a base class or a derivative created?

It is necessary in order to have a static vector of pointers to the base class for all previously created objects. Because when an object is created, the constructor of the base class is called, extra pointers get into the vector, so you need to either clear it of these pointers after the next addition, or check for any question before adding.

  • 3
    It looks like you're crushing a crutch. As soon as static global entities appear, the programmer gains a huge amount of problems. - gbg
  • @gbg and how else to have access to all previously created objects? - bound
  • one
    There is such a cool pattern - class factory. How about its implementation? - gbg
  • @gbg I think it will complicate the understanding of the program, but if there is no suitable answer, you will have to implement - bound
  • one
    @gbg: Did not notice your comment. My answer is just a factory. - VladD

2 answers 2

How to find out in the constructor of a base class, is an object of a base class or a derivative created?

In the constructor of the base class, an object of the base class is created exclusively . Another thing is that it can be part of a heir object.

I do not see a direct method; I would - if it was so impatient - make a special constructor with a dummy parameter, declared as prootected - so that no one could call directly - and call it in a derived class. This would be an indication that this constructor is part of the creation of a derived class object.

Like that:

 class Base { public: Base() { /* ... */ } protected: class ForDerived {}; Base(ForDerived) { /* только из потомков */ } // }; class Derived: public Base { public: Derived():Base(Base::ForDerived()) { } }; 

    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