How can I force a base class function after the constructor of a derived class?

I am looking for a clean C ++ idiom for the following situation:

class SomeLibraryClass {
  public:
    SomeLibraryClass() { /* start initialization */ }
    void addFoo() { /* we are a collection of foos */ }
    void funcToCallAfterAllAddFoos() { /* Making sure this is called is the issue */ }
};
class SomeUserClass : public SomeLibraryClass {
  public:
    SomeUserClass() {
      addFoo();
      addFoo();
      addFoo(); // SomeUserClass has three foos.
    }
};
class SomeUserDerrivedClass : public SomeUserClass {
  public:
    SomeUserDerrivedClass() {
      addFoo(); // This one has four foos.
    }
};

So, I really want SomeLibraryClass to force a call to funcToCallAfterAllAddFoos at the end of the build process. The user cannot put it at the end of SomeUserClass :: SomeUserClass (), which will ruin SomeUserDerrivedClass. If it puts it at the end of SomeUserDerrivedClass, it will never be called for SomeUserClass.

To clarify what I need, imagine that / * run initialization * / gets a lock, and funcToCallAfterAllAddFoos () releases the lock.

The compiler knows when all the initializations for the object are complete, but can I get this information with some nice trick?

+3
5

, , factory. , - .

class LibraryClass
{
public:
   template<typename D>
   static D *GetNewInstance()
   {
      // by assigning the new D to a LibraryClass pointer, you guarantee it derives from LibraryClass at compile time
      // that way, the user can't accidentally type "LibraryClass::GetNewInstance<int>()" and have it work
      LibraryClass *c = new D();
      c->funcToCallAfterAllAddFoos();
      return c;
   }

   ...
};
+9

, . : std::vector<Foo> const &foosToBeAdded, foo s:

class SomeLibraryClass {
  public:
    SomeLibraryClass(std::vector<Foo> const &foosToBeAdded) {
      /* start initialization */
      std::for_each(foosToBeAdded.begin(), foosToBeAdded.end(),
                    std::bind1st(std::mem_fun(&SomeLibraryClass::addFoo), this));
      funcToCallAfterAllAddFoos();
    }
  private:
    void addFoo(Foo const &someFoo) { /* we are a collection of foos */ }
    void funcToCallAfterAllAddFoos() { /* this is now called at the right time */ }
};

class SomeUserClass : public SomeLibraryClass {
  public:
    SomeUserClass() :
      SomeLibraryClass(makeAFooVector())
    {
    }
  private:
    std::vector<Foo> makeAFooVector() { /* return a vector with three Foos */ }
};

, SomeUserClass vector of foo s. foo .

vector s. .

+5

. , . (, ). .

EDIT: , , , Foo .

0

++ , , . ( - , )

. , SomeLibraryClass? AddFoo , , std::vector<Foo>, .

0

addfoo? , , .

functocall

0

Source: https://habr.com/ru/post/1740323/


All Articles