interface_implementation_base
Перейти к навигации
Перейти к поиску
Шаблон класса C++, упрощающий реализацию интерфейсов - наследников InterfaceBase - за счет реализации типичных методов этих интерфейсов на основе заданных параметрами шаблона политик.
template <class impl_t, class interface_disposal_policy, class interface_ref_ctr_policy, class interface_conversion_policy, class ... Interfaces>
struct interface_implementation_base;
impl_t | Потомок класса interface_implementation_base, являющийся конечной реализацией всех интерфейсов Interfaces.... |
interface_disposal_policy | Политика уничтожения экземпляра класса impl_t, реализующего интерфейсы. Класс interface_disposal_policy может предоставлять (полиморфный) метод dispose, реализующий уничтожение объекта, на который указывает параметр метода. Прототип: void dispose(impl_t* ptr) const; . Также класс interface_disposal_policy может не предоставлять метода dispose, тогда уничтожения объекта не производится - например, если объект определен статически или в стеке. Предопределены следующие политики: disposal_policy_do_nothing и disposal_policy_delete. |
interface_ref_ctr_policy | Политика подсчета ссылок на экземпляр impl_t. Если требуется подсчет ссылок на реализацию impl_t, то класс interface_ref_ctr_policy должен предоставлять два метода: std::size_t add_ref();
std::size_t release();
|
interface_conversion_policy | Политика преобразования указателя на экземпляр impl_t к указателю на заданный интерфейс на основе идентификатора. Тип идентификатора задается вложенным типом политики interface_conversion_policy::interface_identifier_type, который должен быть EqualityComparable. Также класс политики должен предоставлять метод convert так, что если ID - идентификатор типа interface_conversion_policy::interface_identifier_type интерфейса, к которому необходимо преобразовать указатель impl на реализацию типа impl_t с помощью политики const interface_conversion_policy policy; , то вызов void* p = policy.convert(ID, &impl); должен присваивать указателю p адрес реализации impl в соответствии с интерфейсом, который идентифицируется параметром ID или nullptr , если интерфейс, заданный идентификатором, не поддерживается. Если тип interface_conversion_policy::interface_identifier_type и/или метод convert, вызываемый над политикой преоразования с доступом только на чтение, классом interface_conversion_policy не предоставлены, то класс interface_implementation_base не предоставляет методов, осуществляющих преобразование (interface_implementation_base::convert, interface_implementation_base::IsInterfaceAvailable, interface_implementation_base::RepresentAs). Предопределенные политики: conversion_policy_none и conversion_policy_map. |
Interfaces... | Интерфейсы, которые реализуются классом impl_t через класс interface_implementation_base путем их наследования последним. |
Открытые методы
Метод | Описание |
---|---|
(конструкторы) | Конструкторы класса interface_implementation_base. |
(деструктор) | Виртуальный деструктор класса interface_implementation_base. |
Release | Метод реализующий закрытие одного экземпляра объекта, реализующего интерфейсы специализации interface_implementation_base. |
AddRef | Условно определенный метод, вызов которого имеет эффект инкремента счетчика ссылок на объект класса interface_implementation_base. |
IsInterfaceAvailable | Условно определенный метод, который проверяет доступность интерфейса по его идентификатору. |
RepresentAs | Условно определенный метод, который осуществляет преобразование в интерфейс, заданный идентификатором. |
Защищенные методы
Метод | Описание |
---|---|
dispose | Метод, реализующий уничтожения объекта interface_implementation_base в соответствии с его политикой interface_disposal_policy. |
add_ref | Метод, реализующий инкремент счетчика ссылок на объект interface_implementation_base. |
release | Метод, реализующий декремент счетчика ссылок на объект interface_implementation_base и, если в результате счетчик становится нулевым, уничтожает объект interface_implementation_base. |
convert | Условно определенный метод, который возвращает указатель на реализацию объекта interface_implementation_base как на программный интерфейс, заданный идентификатором интерфейса. |
Реализует
Интерфейс | Описание |
---|---|
Interfaces...
| Заданные шаблонными параметрами интерфейсы. |
Пример
enum class SomeIdentifierType
{
Id1, Id2, Id3, Id4
};
struct I1:InterfaceBase
{
virtual return_code_t PLATFORM_NATIVE_CALLING_CONVENTION AddRef() const noexcept = 0;
virtual return_code_t PLATFORM_NATIVE_CALLING_CONVENTION IsInterfaceAvailable(SomeIdentifierType id) const noexcept = 0;
virtual return_code_t PLATFORM_NATIVE_CALLING_CONVENTION RepresentAs(SomeIdentifierType id, void** ppInterface) noexcept = 0;
virtual return_code_t PLATFORM_NATIVE_CALLING_CONVENTION CustomMethod() noexcept = 0;
};
struct I2:I1
{
virtual return_code_t PLATFORM_NATIVE_CALLING_CONVENTION CustomMethod2() noexcept = 0;
};
struct I3:I1
{
virtual return_code_t PLATFORM_NATIVE_CALLING_CONVENTION CustomMethod3() noexcept = 0;
};
struct I4:I2
{
virtual return_code_t PLATFORM_NATIVE_CALLING_CONVENTION CustomMethod4() noexcept = 0;
};
struct SomeImplementation: public interface_implementation_base<
SomeImplementation, disposal_policy_delete, ref_ctr_policy_mt, conversion_policy_map<SomeIdentifierType,
conversion_map_entity<SomeIdentifierType, SomeIdentifierType::Id1, compound_conversion_sequence<implicit_conversion_sequence<I1*>, static_conversion_sequence<I2*, I4*>>>,
conversion_map_entity<SomeIdentifierType, SomeIdentifierType::Id2, static_conversion_sequence<I2*>>,
conversion_map_entity<SomeIdentifierType, SomeIdentifierType::Id3, static_conversion_sequence<I3*>>
>, I3, I4>
{
virtual return_code_t PLATFORM_NATIVE_CALLING_CONVENTION CustomMethod() noexcept
{
std::cout << "SomeImplementation::CustomMethod\n";
return CHSVERROR_SUCCESS;
}
virtual return_code_t PLATFORM_NATIVE_CALLING_CONVENTION CustomMethod2() noexcept
{
std::cout << "SomeImplementation::CustomMethod2\n";
return CHSVERROR_SUCCESS;
}
virtual return_code_t PLATFORM_NATIVE_CALLING_CONVENTION CustomMethod3() noexcept
{
std::cout << "SomeImplementation::CustomMethod3\n";
return CHSVERROR_SUCCESS;
}
virtual return_code_t PLATFORM_NATIVE_CALLING_CONVENTION CustomMethod4() noexcept
{
std::cout << "SomeImplementation::CustomMethod3\n";
return CHSVERROR_SUCCESS;
}
~SomeImplementation()
{
std::cout << "SomeImplementation::~SomeImplementation\n";
}
};
struct SomeImplementation2: public interface_implementation_base<
SomeImplementation, disposal_policy_delete, ref_ctr_policy_mt,
CONVERSION_POLICY_MAP(SomeIdentifierType,
CONVERSION_MAP_ENTITY(SomeIdentifierType::Id1, compound_conversion_sequence<implicit_conversion_sequence<I1*>, static_conversion_sequence<I2*, I4*>>),
CONVERSION_MAP_ENTITY(SomeIdentifierType::Id2, static_conversion_sequence<I2*>),
CONVERSION_MAP_ENTITY(SomeIdentifierType::Id3, static_conversion_sequence<I3*>)),
I3, I4>
{
virtual return_code_t PLATFORM_NATIVE_CALLING_CONVENTION CustomMethod() noexcept
{
std::cout << "SomeImplementation2::CustomMethod\n";
return CHSVERROR_SUCCESS;
}
virtual return_code_t PLATFORM_NATIVE_CALLING_CONVENTION CustomMethod2() noexcept
{
std::cout << "SomeImplementation2::CustomMethod2\n";
return CHSVERROR_SUCCESS;
}
virtual return_code_t PLATFORM_NATIVE_CALLING_CONVENTION CustomMethod3() noexcept
{
std::cout << "SomeImplementation2::CustomMethod3\n";
return CHSVERROR_SUCCESS;
}
virtual return_code_t PLATFORM_NATIVE_CALLING_CONVENTION CustomMethod4() noexcept
{
std::cout << "SomeImplementation2::CustomMethod3\n";
return CHSVERROR_SUCCESS;
}
~SomeImplementation2()
{
std::cout << "SomeImplementation2::~SomeImplementation2\n";
}
};
int main(int argc, char**)
{
I1* pI1;
I2* pI2;
I3* pI3;
pI2 = new SomeImplementation;
pI2->CustomMethod2();
pI2->RepresentAs(SomeIdentifierType::Id1, (void**) &pI1);
pI2->Release();
pI1->RepresentAs(SomeIdentifierType::Id3, (void**) &pI3);
pI1->CustomMethod();
pI3->CustomMethod3();
pI1->Release();
pI3->Release();
pI2 = new SomeImplementation2;
pI2->CustomMethod2();
pI2->RepresentAs(SomeIdentifierType::Id1, (void**) &pI1);
pI2->Release();
pI1->RepresentAs(SomeIdentifierType::Id3, (void**) &pI3);
pI1->CustomMethod();
pI3->CustomMethod3();
pI1->Release();
pI3->Release();
return 0;
}