如何在派生类构造函数之后强制调用基类函数?

Mik*_*ins 3 c++ inheritance constructor

我正在为以下情况寻找一个干净的C++习语:

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.
    }
};
Run Code Online (Sandbox Code Playgroud)

所以,我真正想要的是SomeLibraryClass在构造过程结束时强制执行funcToCallAfterAllAddFoos的调用.用户不能将它放在SomeUserClass :: SomeUserClass()的末尾,这会弄乱SomeUserDerrivedClass.如果他把它放在SomeUserDerrivedClass的末尾,那么它永远不会被SomeUserClass调用.

为了进一步说明我的需要,想象一下/*start initialization*/获取一个锁,funcToCallAfterAllAddFoos()释放一个锁.

编译器知道什么时候所有完成对象的初始化,但我可以通过一些不错的把戏在这个信息得到什么?

mos*_*ald 9

我可能会用某种工厂来实现它.以下代码应该被读作伪代码,我还没有尝试编译它或任何东西.

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;
   }

   ...
};
Run Code Online (Sandbox Code Playgroud)

  • 不,任何构造函数传递方法都可以工作,您只需构建从派生类传递的集合. (2认同)
  • @Thomas:我没有看到将构造函数公开是一个要求.工厂可以(也可能应该)成为朋友类/功能.请注意,这不会破坏封装,也不会增加耦合:工厂和创建的对象已经紧密耦合,并且您可以控制工厂方法,因此您可以像实现类的方法一样控制. (2认同)

Tho*_*mas 5

我不确定这是可能的.但是,你可以稍微重新设计一下:给你的基类构造函数一个参数std::vector<Foo> const &foosToBeAdded,让派生类传递正确的foos:

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 */ }
};
Run Code Online (Sandbox Code Playgroud)

该模式可以通过使被扩展SomeUserClass构造也接收vectorFoo第 然后Foo在调用基类构造函数之前,它会将自己的s 添加到列表中.

您也可以传递迭代器而不是vectors.留下来作为锻炼.