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

时间:2010-01-26 09:21:39

标签: c++ oop

最近我一直在编写与此类似的代码:

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(..);直接或间接从工厂获得一个。

但是。我没有看到这种方法在其他地方使用得太多。以上是好的做法吗?对于简单的案例,还有其他/更好的选择吗?

5 个答案:

答案 0 :(得分:6)

你总是要尽可能地隐藏起来。你的方式(将实现类放入.cpp)是在c ++中执行此操作的常用方法。

答案 1 :(得分:2)

这是隐藏客户端实施细节的好方法。如果您在Windows中工作,您可能还会考虑使用__interface而不是抽象基类。

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

答案 2 :(得分:1)

当然 - 它看起来像a form of the factory pattern。工厂的用户对其内部细节不感兴趣,他们只关心它所创造的东西。

答案 3 :(得分:1)

隐藏实现细节的过程称为Encapsulation。 最小化用户构建依赖关系的过程称为Insulation。约翰·拉科斯(John Lakos)写了一本关于这两个主题的伟大(但时效)的书:

http://www.amazon.com/Large-Scale-Software-Design-John-Lakos/dp/0201633620

答案 4 :(得分:0)

最大限度地减少对实现细节的依赖确实很好,隐藏抽象基类(ABC,又称接口)之外的东西是一个很好的惯用解决方案。

使用ABC的缺点是你失去了你班级的价值语义,这可能是或不可接受/可取的。

一种隐藏实现细节而没有这个缺点的技术是Pimpl。猜猜你应该知道。

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