我向用户提供了一个SDK,允许他们用C ++编写DLL来扩展软件。
SDK标头主要包含接口类定义。这些类有两种类型:
我在手册中编写了不应该被子类化的接口,并且只能通过应用程序提供的对象上的指针来使用。但是在某些地方,如果你不阅读手册,那么在SDK中将它们子类化是很诱人的。
是否可以阻止对SDK标头中的某些接口进行子类化?
答案 0 :(得分:0)
只要客户端不需要使用指针即可
将它传回你的DLL,你可以使用前向声明;
你不能从一个不完整的类型派生出来。 (面对类似的时候
最近的情况,我去了整个猪,并设计了一个特殊的包装类型
基于void*
。接口代码中有很多内容,但是
除了将值传递回去之外,客户端无法做很多事情
我。)
如果有问题的类实现了客户端必须的接口 也用,有两种解决方案。首先是改变这个, 用自由函数替换每个成员函数 指向该类型的指针,只提供一个前向声明。该 第二是使用类似的东西:
class InternallyVisibleInterface;
class ClientVisibleInterface
{
private:
virtual void doSomething() = 0;
ClientVisibleInterface() = default;
friend class InternallyVisibleInterface;
protected: // Or public, depending on whether the client should
// be able to delete instances or not.
virtual ~ClientVisibleInterface() = default;
public:
void something();
};
并在你的DLL中:
class InternallyVisibleInterface : public ClientVisibleInterface
{
protected:
InternallyVisibleInterface() {}
// And anything else you need. If there is only one class in
// your application which should derive from the interface,
// this is it. If there are several, they should derive from
// this class, rather than ClientVisibleInterface, since this
// is the only class which can construct the
// ClientVisibleInterface base class.
};
void ClientVisibleInterface::something()
{
assert( dynamic_cast<InternallyVisibleInterface*>( this ) != nullptr );
doSomething();
}
这提供了两个级别的保护:第一,虽然派生
直接来自ClientVisibleInterface
是可能的,这是不可能的
结果类有一个构造函数,所以它不能
实例化。其次,如果客户端代码以某种方式作弊,
如果他这样做会有运行时错误。
你可能不需要同时保护;一个或另一个应该
满足。私有构造函数将导致编译时错误,
而不是运行时的。另一方面,如果没有它,你就不会
甚至不得不提到InternallyVisibleInterface
的名字
分布式标题。
答案 1 :(得分:0)
一旦开发人员拥有开发环境,他几乎可以做任何事情,你甚至不应该试图控制它。
恕我直言,你可以做的最好的事情是确定核心应用程序和扩展DLL之间的限制,并确保从那些 或正确的类中获取的对象,如果它们是中断消息则中止不是。
使用RTTI和typeid
通常不赞成,因为它通常是糟糕的OOP设计的标志:在普通用例中,调用虚方法足以调用适当的代码。但我认为在您的使用案例中可以安全地考虑它。