隐藏C++接口的具体实现

Hiding specific implementation of C++ interface

我对更高级的 C++ 功能比较陌生...所以请记住这一点 ;)

我最近定义了一些 class 的接口,当然,只包含纯虚函数。

然后,我在单独的文件中实现了该接口的特定版本。

问题是...如何在用户端调用该接口的具体实现,而不泄露该具体实现的内部结构?

因此,如果我有一个 Interface.h 头文件,如下所示:

class Interface
{
  public:
    Interface(){};
    virtual ~Interface(){};
    virtual void InterfaceMethod() = 0;
}

然后,一个特定的 Implementation.h 头文件如下所示:

class Implementation : public Interface
{
  public:
    Implementation(){};
    virtual ~Implementation(){};
    void InterfaceMethod();
    void ImplementationSpecificMethod();
}

最后,在 main 下,我有:

int main()
{
  Interface *pInterface = new Implementation();
  // some code
  delete pInterface;
  return 0;
}

如何在不泄露来自 "main" 的 Implementation.h 的详细信息的情况下做这样的事情?有没有办法告诉"main"...哎,"Implementation"只是"Interface"的一种;并将其他所有内容保存在单独的库中?

我知道这个一定是一个重复的问题...但是我找不到明确的答案。

感谢您的帮助!

您可以通过使用 PIMPL 之类的工具隐藏 .cpp 文件中的实现细节,从而在头文件中隐藏实现的一些内部细节(私有)class。

有关 pimpl 习语的更多讨论,请参阅 Is the pImpl idiom really used in practice?

你可以使用工厂。

Header:

struct Abstract
{
    virtual void foo() = 0;
}

Abstract* create();

来源:

struct Concrete : public Abstract
{
    void foo() { /* code here*/  }
}

Abstract* create()
{
    return new Concrete();
}

虽然工厂解决方案似乎更适合 OP 问题,但使用 PIMPL idiom 的版本也可以解决同样的问题。

虽然两个版本都通过指针进行间接调用,但 PIMPL 版本设法避免了虚拟接口,但代价是更加人为。

头文件:

class Interface
{
    struct Implementation;
    std::unique_ptr< Implementation > m_impl;

  public:
    Interface();
    ~Interface();
    void InterfaceMethod();
};

执行文件:

class Interface::Implementation
{
  public:
    void ImplementationSpecificMethod()
    {
        std::cout << "ImplementationSpecificMethod()\n";
    }
};

Interface::Interface()
    : m_impl( std::make_unique< Interface::Implementation >( ) )
{ }

Interface::~Interface() = default;

void Interface::InterfaceMethod( )
{
    m_impl->ImplementationSpecificMethod();
}

主文件:

int main()
{
    Interface i;
    i.InterfaceMethod(); // > ImplementationSpecificMethod()
}

See it online.