3

在我的 C++ 应用程序中,我有一个如下所示的界面:

class ICalculator
   {
   public:
      virtual double calculateValue(double d) = 0;
   };

我有这个接口的实现,如下所示:

class MySpecificCalculator
   {
   public:
      virtual double calculateValue(double d);
   };

现在我的同事抱怨这个并告诉我最好保护 calculateValue 方法。这样,我们可以保证调用者总是通过接口而不是直接实现。

这是一个正确的观察吗?保护接口的实现真的更好吗?或者我们甚至不能将其设为私有吗?

4

2 回答 2

10

你的同事是对的。

永远不要公开虚拟功能。

准则 #1:更喜欢使用模板方法使接口成为非虚拟的。

准则 #2:更喜欢将虚拟函数设为私有。

准则#3:只有当派生类需要调用虚函数的基实现时,才使虚函数受到保护。

仅针对析构函数的特殊情况:

准则 #4:基类析构函数应该是公共的和虚拟的,或者是受保护的和非虚拟的。

于 2010-11-10T08:40:07.343 回答
0

听起来你的同事的意思是:

class ICalculator
{
public:
    virtual double calculateValue(double d) const = 0;
};

class MySpecificCalculator : public ICalculator
{
protected:
    double calculateValue(double d) const;
};

void Calc(double d, const ICalculator& c)
{
    std::cout << "Result = " << c.calculateValue(d) << std::endl;
}

int main ()
{
    MySpecificCalculator c;
    c.calculateValue(2.1);  // dont do this
    Calc(2.1, c);  // do this instead
    return 0;
}

我看不出这种设计有什么好处。为什么不能从具体的参考中调用计算。要将 calculateValue 移动到派生类中的 protected,会破坏基类的约定。您不能使用 MySpecificCalculator 来计算值,但它的基类是这样说的。

顺便说一句,这种行为不是由 Chubsdad 解释的 NVI 习语建模的(这是“正确”的方式)。

于 2010-11-10T10:23:39.863 回答