| #pragma once
#include <iostream>
#include <memory>
struct IDelegationTest
{
virtual bool getter() = 0;
virtual bool setter(bool b) = 0;
virtual void jobImpl(bool b, int i) = 0;
virtual void jobImpl(bool b, int i, std::string s) = 0; // !!! А что будет с этой перегрузкой?
virtual int jobImpl2(bool b, int i) = 0;
};
struct DelegationTestImpl : public IDelegationTest
{
int n = 0;
virtual bool getter() override
{
std::cout << "DelegationTestImpl::getter(), n: " << n << "\n";
return true;
}
virtual bool setter(bool b) override
{
std::cout << "DelegationTestImpl::setter(bool b), b: " << b << ", n: " << n << "\n";
return true;
}
virtual void jobImpl(bool b, int i) override
{
std::cout << "DelegationTestImpl::jobImpl(bool b, int i), b: " << b << ", i: " << i << ", n: " << n << "\n";
}
virtual int jobImpl2(bool b, int i) override
{
std::cout << "DelegationTestImpl::jobImpl2(bool b, int i), b: " << b << ", i: " << i << ", n: " << n << "\n";
return n;
}
};
struct DelegatorImpl : public IDelegationTest
{
std::vector< std::shared_ptr<IDelegationTest> > impls;
template <typename Return, typename... Args>
Return delegateCall( Return(IDelegationTest::*func)(Args...), Args...)
{
// !!! Тут assert на тему impls не должен быть пустым
std::vector<std::shared_ptr>::const_iterator it = impls.begin();
// !!! Или assert тут по it!=impls.end();
// Получаем результат
auto res = it->func(Args...); ++it;
for(; it!=impls.end(); ++it)
{
// Вызываем метод для всех экземпляров имплементаций
it->func(Args...); ++it;
}
return res;
}
//
template <typename... Args>
void delegateCall( void(IDelegationTest::*func)(Args...), Args...)
{
std::vector<std::shared_ptr>::const_iterator it = impls.begin();
for(; it!=impls.end(); ++it)
{
// Вызываем метод для всех экземпляров имплементаций
it->func(Args...); ++it;
}
}
// !!! Тут ещё проблема, а что будет с перегруженными виртуальными методами?
virtual bool getter() override
{
return delegateCall(getter);
}
virtual bool setter(bool b)
{
return delegateCall(setter, b);
}
virtual void jobImpl(bool b, int i)
{
delegateCall(jobImpl, b, i);
}
virtual void jobImpl2(bool b, int i)
{
return delegateCall(jobImpl2, b, i);
}
};
inline
std::shared_ptr<IDelegationTest> makeDelegator()
{
DelegatorImpl impl;
impl.impls.emplace_back(std::make_shared<DelegationTestImpl>(1));
impl.impls.emplace_back(std::make_shared<DelegationTestImpl>(2));
// !!! Тут надо создать экземпляр DelegatorImpl, но вернуть надо std::make_shared<IDelegationTest>
return std::make_shared<IDelegationTest>(impl);
}
int main()
{
std::shared_ptr<IDelegationTest> pDelegator = makeDelegator();
pDelegator->getter();
pDelegator->setter(true);
pDelegator->jobImpl(false, 3);
pDelegator->jobImpl2(true, 5);
}
|