抽象类 - 在C++实践中隐藏实现

6

最近我一直在写类似于以下代码的内容:

messagehandler.h:

#include "message.h"
class MessageHandler {
public:
   virtual ~MessageHandler() {}
   virtual void HandleMessage(Message *msg) = 0:
};

persistmessagehandler.h:

MessageHandler *CreatePersistMessageHandler();

persistmessagehandler.cpp:

#include "messagehandler.h"
#include "persist.h"

class PersistMessageHandler : public MessageHandler {
private:
   PersistHandle ph;
   size_t count;
   InternalCheck();
public:
   PersistMessageHandler(int someParam);
   virtual ~PersistMessageHandler ();
   virtual void HandleMessage(Message *msg):
};
PersistMessageHandler::PersistMessageHandler(int someParam)
{
  ph.Initialize();
}
... rest of implementation.

MessageHandler *CreatePersistMessageHandler(int someParam)
{
  return new PersistMessageHandler(someParam);
}

这里的思路是隐藏PersistMessageHandler。客户端不需要为PersistMessageHandler类包含头文件,也不需要包含实现可能需要的所有包括和类型,以更清晰地分离接口和实现。它总是会被动态分配的。
所有PersistMessageHandler用户只需直接调用CreatePersistMessageHandler(..); 或者从工厂间接获取一个。
但是,我很少见到这种方法在其他地方使用。上述方法是否是良好的实践?对于简单情况,是否有其他/更好的替代方案?

为什么有人会把“Message”缩写成“Messge”?这是打错了吗? - unwind
很好的问题!我经常这样做,一直想知道它是否合规。我的声明是:std :: auto_ptr <MessageHandler> CreatePersistMessageHandler(); - Travis Gockel
请参见https://dev59.com/U3RA5IYBdhLWcg3wyRJ7。 - Frank
5个回答

6

你总是要尽可能地隐藏代码实现。在C++中,将实现类放入.cpp文件中是一种常见的方法。


2

这是一种很好的方法,可以隐藏实现细节,不让客户端知道。如果您在Windows上工作,您可能还可以考虑使用__interface而不是抽象基类。

接口是MSVC编译器的扩展,看起来像是抽象基类,但创建和销毁规则与普通的C++类不同。这是在Windows中工作的标准方式,因此有系统支持的设施可用于处理进程外对象并在.NET代码中使用它们。


1
当然 - 它看起来像是工厂模式的一种形式。 工厂的用户不关心其内部细节,他们只关心它所创建的东西。

1

0

尽量减少对实现细节的依赖确实是很好的,将事物隐藏在抽象基类(ABC,也称接口)之外是一个好的惯用解决方案。

使用ABC的缺点是您失去了类的值语义,这可能是可以接受/期望的,也可能不可接受/不期望。

一种在没有这种缺点的情况下也可以隐藏实现细节的技术是Pimpl。我想你应该知道。

在大多数情况下,我更喜欢使用ABC。


@CraigMcQueen 打错了,应该是 ABC(抽象基类)。谢谢! - Alexander Poluektov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接