【问题标题】:Abstract class - hiding implementation in C++ practice抽象类——C++实践中的隐藏实现
【发布时间】:2010-01-26 09:21:38
【问题描述】:

最近一直在写类似这样的代码:

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”?是不是笔误?
  • 好问题!我一直这样做,一直想知道这是否是犹太洁食。除了我的声明是:std::auto_ptr<MessageHandler> CreatePersistMessageHandler();

标签: c++ oop


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        隐藏实现细节的过程称为Encapsulation。 为您的用户最小化构建依赖的过程称为Insulation。约翰·拉科斯 (John Lakos) 写了一本很棒(但陈旧)的书,专门讨论这两个主题:

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

        【讨论】:

          【解决方案5】:

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

          使用 ABC 的缺点是您会丢失类的值语义,这可能是或不可能是可接受/可取的。

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

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

          【讨论】:

          • @CraigMcQueen 错字,应该是 ABC(抽象基类)。谢谢!
          猜你喜欢
          • 1970-01-01
          • 2021-06-02
          • 1970-01-01
          • 2020-12-11
          • 1970-01-01
          • 1970-01-01
          • 2018-02-12
          • 2017-03-20
          • 2012-05-03
          相关资源
          最近更新 更多