隐藏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()
}
我对更高级的 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()
}