如何确保从派生类调用纯虚方法?

Sku*_*Sku 4 c++

我有以下情况:

#include <iostream>

class Base{
  public:
    Base() = default;
    virtual void make_sure_im_called() = 0;
};

class Child : public Base {
  public:
    virtual void make_sure_im_called()
    {
      std::cout << "I was called as intended." << std::endl;
    };
}
Run Code Online (Sandbox Code Playgroud)

这是因为我希望从Base派生的每个类都实现make_sure_im_called()(通过使其成为纯虚拟成功完成).但是我如何断言有人从Base派生一个新类也被迫调用该函数?似乎我从基类尝试的所有内容都会因为缺少实现而失败.

JVA*_*pen 5

在C++中,没有内置构造可以执行您想要的操作,但是,您可以自己执行它.

#include <iostream>

class Base{
  public:
    Base() = default;
    void make_sure_im_called() {
       before_make_sure_im_called();
       // Your own code
       after_make_sure_im_called();
    }
  protected:
    // Hooks to be implemented
    virtual void before_make_sure_im_called() = 0;
    virtual void after_make_sure_im_called() = 0;
};

class Child : public Base {
  protected:
    virtual void before_make_sure_im_called() override
    {
      std::cout << "I was called as intended." << std::endl;
    };
    virtual void after_make_sure_im_called() override {}
}
Run Code Online (Sandbox Code Playgroud)

这导致2个虚拟调用(大多数情况下,您可以使用其中1个存活).如果有人打电话make_sure_im_called,现在这将调用纯虚拟呼叫.

通过使它们受到保护,减少了它们被调用的可能性,因为只有派生类可以访问它们.

强制在实例的生命周期中调用此方法.

make_sure_im_called无法从构造函数中调用该方法Base.没有可以强制执行此操作的构造,但如果不是这样,您可以让程序崩溃.

#include <iostream>

class Base{
  public:
    Base() = default;
    ~Base() { assert(_initialized && "Some message"); }
    void make_sure_im_called() {
       before_make_sure_im_called();
       // Your own code
       after_make_sure_im_called();
       _initialized = true;
    }
  protected:
    // Hooks to be implemented
    virtual void before_make_sure_im_called() = 0;
    virtual void after_make_sure_im_called() = 0;

  private:
      bool _initialized{false};
};

class Child : public Base {
  protected:
    virtual void before_make_sure_im_called() override {};
    virtual void after_make_sure_im_called() override {}
}
Run Code Online (Sandbox Code Playgroud)

通过保留_initialized成员,您可以跟踪被调用的方法.在Dtor中,如果这是假的,你可以对此断言并使程序崩溃(仅调试构建?).练习给读者:获得复制/移动构造/作业权.

然而,解决方案可能不那么优雅,至少它比没有任何东西更好.人们甚至可以将其作为API的一部分进行记录.