在我的C ++应用程序中,我有一个如下所示的界面:
class ICalculator
{
public:
virtual double calculateValue(double d) = 0;
};
我有这个界面的实现,如下所示:
class MySpecificCalculator
{
public:
virtual double calculateValue(double d);
};
现在我的同事抱怨这个并且告诉我最好让calculateValue方法受到保护。这样,我们可以保证调用者总是通过接口而不是通过直接实现传递。
这是正确的观察吗?是否真的更好地保护接口的实现?或者我们不能把它私有化吗?
答案 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习语建模的(这是'正确的'方式)。