在接口中公开方法的优点是什么,但在实现中受到保护?

时间:2010-11-10 08:37:48

标签: c++ interface virtual access-specifier

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

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

我有这个界面的实现,如下所示:

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

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

这是正确的观察吗?是否真的更好地保护接口的实现?或者我们不能把它私有化吗?

2 个答案:

答案 0 :(得分:10)

你的同事是对的。

Never make virtual functions public.

  

准则#1:更喜欢制作   使用Template接口非虚拟   方法。

     

指南#2:更喜欢   使虚拟功能变得私密。

     

准则#3:仅限派生类   需要调用基础实现   一个虚拟功能,使   虚拟功能受保护。

     

对于析构函数的特殊情况   只有:

     

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

答案 1 :(得分: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来计算Value,但它的基类是这样说的。

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