我如何确保从我的派生类中调用纯虚拟方法

How can I assure a pure virtual method is called from my derived class?

本文关键字:派生 调用 方法 虚拟 我的 何确保 确保      更新时间:2023-10-16

我有以下情况:

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

是这样,我希望每个从基础派生的类都实现make_sure_im_called(((这是通过使其纯虚拟的(成功完成的。但是,我该如何断言某人也从基地中得出新的班级也被迫调用该功能?看来我从基类尝试的一切都会因丢失的实现而失败。

在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 {}
}

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

通过使它们受到保护,将其称为降低的机会,因为只有派生的类才能访问它们。

在实例的寿命中强制调用此方法。

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

#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 {}
}

通过保持_initialized成员,您可以跟踪所调用的方法。在DTOR中,您可以在此上断言并崩溃程序(如果是false((仅辩论构建?(。向读者锻炼:正确获取复制/移动构造/分配。

解决方案可能不是那么优雅,至少它比一无所有要好。甚至可以将其作为API的一部分进行记录。