一种在 C++ 中强制使用接口的方法
在 C++ 中,假设我有一个类 Derived
,它实现了一个接口类 BaseInterface
,其中 < code>BaseInterface 仅具有纯虚函数和虚拟析构函数:
class BaseInterface
{
public:
virtual void doSomething() = 0;
~BaseInterface(){}
};
class Derived : public BaseInterface
{
public:
Derived() {}
~Derived(){}
protected:
virtual void doSomething();
private:
int x;
};
Derived
类层次结构之外的任何类都不应调用 Derived::doSomething()
直接,即应该只能通过 BaseInterface 类进行多态访问。为了执行此规则,我已将 Derived::doSomething()
设为受保护。这很有效,但我正在寻找关于这种方法的赞成/反对意见。
谢谢!
肯
In C++, let's say I have a class Derived
that implements an interface class BaseInterface
, where BaseInterface
has only pure virtual functions and a virtual destructor:
class BaseInterface
{
public:
virtual void doSomething() = 0;
~BaseInterface(){}
};
class Derived : public BaseInterface
{
public:
Derived() {}
~Derived(){}
protected:
virtual void doSomething();
private:
int x;
};
No classes outside the Derived
class hierarchy should call Derived::doSomething()
directly, i.e., it should only be accessed polymorphically through the BaseInterface
class. To enforce this rule, I have made Derived::doSomething()
protected. This works well, but I'm looking for opinions pro/con regarding this approach.
Thanks!
Ken
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我认为您正在寻找非虚拟接口 (NVI) 模式:调用受保护或私有虚拟实现的公共非虚拟接口:
I think you're looking for the non-virtual interface (NVI) pattern: a
public
non-virtual interface that calls a protected or privatevirtual
implementation:如果它是接口的一部分,为什么您不希望用户调用它?请注意,事实上,他们可以调用它:
static_cast(o).doSomething()
只是一种尴尬的说法o.doSomething()
。 使用接口的意义是什么...如果对象满足接口,那么你应该能够使用它,或者我错过了什么?由于您实际上并没有阻止任何人调用这些方法,因此我认为没有任何特殊原因使代码变得更复杂(包括类和类的用户)。请注意,这与非虚拟接口完全不同,因为在这种习惯用法中,虚拟函数不能公开访问(在任何级别),而在您的情况下,目的是允许访问,并使其变得麻烦。
If it is part of the interface, why would you not want users to call it? Note that as it is, they can call it:
static_cast<BaseInterface&>(o).doSomething()
is just an awkward way of sayingo.doSomething()
. What is the point of using the interface... if the object fulfills the interface, then you should be able to use it, or am I missing something?Since you are not actually blocking anyone from calling the methods, I don't see a point in making the code more complex (both the class and users of the class) for no particular reason. Note that this is completely different from the Non-Virtual Interface in that in this idiom virtual functions are not accessible publicly (at any level) while in your case, the intention is allowing access, and making it cumbersome.
标准 ISO/IEC 14882:2003(E) 11.6.1 中也提到了您所做的事情,并相信您是正确的。除此之外,在给定的示例中,成员函数不是纯虚拟的。据我所知,它也应该适用于纯虚函数。
What you are doing is also mentioned in standard ISO/IEC 14882:2003(E) 11.6.1 and believe you are correct. Other than the fact, the member function isn't pure virtual in the given example. It should hold for pure virtual functions too, AFAIK.
关键是你的代码的其余部分。只接受 BaseInterface* 作为任何需要 doSomething() 调用的方法的参数。客户端程序员被迫从接口派生以使其代码能够编译。
The key is the rest of your code. Only accept a BaseInterface* as an argument to any methods that require the doSomething() call. The client programmer is forced to derive from the interface to make his code compile.
这对我来说毫无意义。无论您调用哪个指针
doSomething()
,您仍然会得到大多数派生类中定义的方法。考虑以下场景:This makes no sense to me. Regardless of which pointer you call
doSomething()
, you would still wind up with the method defined in most derived class. Consider the following scenario: