#include <memory>
namespace restricted
{
struct A
{
virtual ~A() {}
virtual int value_a() const { return a ; }
protected:
int a = 0 ;
virtual void value_a( int i ) { a = i ; }
};
struct B : A
{
virtual int value_b() const { return b ; }
protected:
int b = 0 ;
virtual void value_b( int i ) { b = i ; }
};
}
namespace exposed
{
struct A : restricted::A
{
using restricted::A::value_a ;
} ;
struct B : restricted::B
{
using restricted::B::value_a ;
using restricted::B::value_b ;
} ;
}
int main()
{
auto exposed_a = std::make_shared<exposed::A>() ;
int v = exposed_a->value_a() ;
exposed_a->value_a(v) ; // fine, exposed
auto exposed_b = std::make_shared<exposed::B>() ;
v = exposed_b->value_a() ;
exposed_b->value_a(v) ; // fine, exposed
v = exposed_b->value_b() ;
exposed_b->value_b(v) ; // fine, exposed
std::shared_ptr<restricted::A> restricted_a(exposed_a) ; // fine, exposed::A => restricted::A
v = restricted_a->value_a() ; // fine
// restricted_a->value_a(v) ; // *** error **** restricted::A::value_a(int) is protected
restricted_a = exposed_b ; // also fine, exposed::B => restricted::A
std::shared_ptr<restricted::B> restricted_b(exposed_b) ; // fine, exposed::B => restricted::B
v = restricted_b->value_a() ; // fine
// restricted_b->value_a(v) ; // *** error **** restricted::B::value_a(int) is protected
v = restricted_b->value_b() ; // fine
// restricted_b->value_b(v) ; // *** error **** restricted::B::value_b(int) is protected
}