3

我有一个客户可以“关闭”的基类:

struct base {
  void shutdown() {
    //code
  }
};

但是客户可以(如果他们愿意)创建一个子类来满足他们自己的需求:

struct der : public base {
  void shutdown(double some, int other, bool parameters) {
    //custom shutdown stuff
    base::shutdown(); //<- thus MUST be called
  }
};

问题是客户必须记得调用base::shutdown()(超类创建者将记录这个给子类开发者)。这似乎很容易出错,因为在 compile-time 没有强制执行

是否有其他设计模式可以以某种方式解决这个问题?

4

2 回答 2

5

不幸的是,这是您在编写代码时“必须做正确的事情”的情况之一。这适用于编程中的许多事情。如果你在计算某事时没有做正确的计算,那也是错误的。或者,如果您两次调用一个只应调用一次的函数。或者在必须调用它时根本不调用它。所有这些事情都是“做错了”。你无法阻止程序员犯错...

当然,如果你没有添加一堆额外的参数,你可以通过在基类中添加一个不会被覆盖的非虚拟函数来“反向”执行,然后让基类调用派生类中的virtual函数。正如我所说,如果您有需要进入派生类的基类中不存在的参数,则它不起作用。

我的意思的一个例子:

struct base {
  void shutdown() final {   // final: it can't be overridden in derived class
    do_shutdown();   // Calls derived function's 
    // ... more code here ... 
  }
  virtual void do_shutdown() { }    // default is "do nothing". 
};


struct der: public base
{
   // not overriding `shutdown`, but overriding `do_shutdown`
   void do_shutdown()
   {
      .. some code goes here .. 
   }
}

现在调用der->shutdown()将调用基类的实现,它do_shutdown在完成基类中的shutdown.

但是,就像我说的那样,当你这样做时,你不能添加额外的参数——事实上,派生一个类并改变参数是“错误的”——不是那么错误,你不可能永远这样做,但它往往是使用继承多态是一件坏事,因为多态的全部目的是有一些通用代码“不知道它是基类对象、派生对象还是派生对象”——所以如果它需要知道哪个传递正确数量的参数的对象,它变得有点毫无意义。

于 2013-07-04T23:50:28.527 回答
2

我不会担心的。它类似于派生类的赋值运算符。如果子类开发人员忘记调用它,这不是你的错,但如果不是,也不是错误。

有关该主题的 C++ 常见问题解答条目

于 2013-07-04T23:53:16.560 回答