我有一个基类,客户可以"关闭":
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()
(超类创建者会将此文档记录为子类开发人员)。这似乎容易出错,因为在编译时没有强制执行。
是否有其他设计模式可以某种方式解决这个问题?
答案 0 :(得分:5)
不幸的是,这是在编写代码时“必须做正确的事”的情况之一。这适用于编程中的许多事情。如果在计算某些东西时没有做正确的计算,那也是错误的。或者如果你调用一次只能调用一次的函数。或者在必须被调用时根本不调用它。所有这些都是“做错了”。你不能阻止程序员犯错误......
当然,如果你还没有添加一堆额外的参数,你可以通过在基类中使用非虚拟函数来反向执行它,而不会被覆盖,然后让基数-class在派生类中调用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
中完成。
但是,就像我说的那样,你不能在执行此操作时添加额外的参数 - 事实上,派生一个类并更改参数是“错误的” - 没有错,你不可能做到这一点,但它使用继承多态时往往是一件坏事,因为多态的整个目的是有一些常见的代码“不知道它是基类对象,派生1对象还是派生2对象” - 所以如果它需要要知道哪种对象传递正确数量的参数,它就会变得毫无意义。
答案 1 :(得分:2)
我不担心。它类似于派生类的赋值运算符。如果子类开发人员忘记调用它,那不是你的错,但如果它不是,那也不是错误。