Я относительно новичок в более продвинутых возможностях C ++ … Так что имейте это в виду;)
Недавно я определил интерфейс для некоторого класса, состоящего, конечно, только из чисто виртуальных функций.
Затем я реализовал конкретную версию этого интерфейса в отдельных файлах.
Вопрос в том … Как вызвать конкретную реализацию этого интерфейса на стороне пользователя, не раскрывая внутреннюю часть этой конкретной реализации?
Так что, если у меня есть заголовочный файл Interface.h, который выглядит следующим образом:
class Interface
{
public:
Interface(){};
virtual ~Interface(){};
virtual void InterfaceMethod() = 0;
}
Затем конкретный заголовочный файл Practice.h, который выглядит следующим образом:
class Implementation : public Interface
{
public:
Implementation(){};
virtual ~Implementation(){};
void InterfaceMethod();
void ImplementationSpecificMethod();
}
Наконец, по основному, у меня есть:
int main()
{
Interface *pInterface = new Implementation();
// some code
delete pInterface;
return 0;
}
Как я могу сделать что-то вроде этого, не раскрывая детали реализации.h, из «main»? Разве нет способа сказать «основной» … Эй, «Реализация» — это просто тип «Интерфейса»; и хранить все остальное в отдельной библиотеке?
я знаю это должен быть повторяющимся вопросом … Но я не мог найти четкий ответ на это.
Спасибо за помощь!
Вы можете использовать фабрику.
Заголовок:
struct Abstract
{
virtual void foo() = 0;
}
Abstract* create();
Источник:
struct Concrete : public Abstract
{
void foo() { /* code here*/ }
}
Abstract* create()
{
return new Concrete();
}
Вы можете скрыть некоторые из внутренних деталей (рядов) вашего класса реализации от простого просмотра в заголовочном файле, используя что-то вроде PIMPL, чтобы скрыть детали реализации в файле .cpp.
Увидеть Действительно ли идиома pImpl используется на практике? для более подробного обсуждения идиомы pimpl.
Хотя заводское решение лучше подходит для OP, я думаю, что версия PIMPL также может решить те же проблемы. Это немного более изобретательно, но избегает виртуального интерфейса:
// Header file:
class Interface
{
struct Implementation;
std::unique_ptr< Implementation > m_impl;
public:
Interface();
~Interface();
void InterfaceMethod();
};
// Implementation file:
class Interface::Implementation
{
public:
void ImplementationSpecificMethod()
{
std::cout << "Bla" << std::endl;
}
};
Interface::Interface()
: m_impl( std::make_unique< Interface::Implementation >( ) )
{ }
Interface::~Interface() = default;
void Interface::InterfaceMethod( )
{
m_impl->ImplementationSpecificMethod();
}
// Main file:
int main()
{
Interface i;
i.InterfaceMethod(); // prints Bla
}