Archived

This topic is now archived and is closed to further replies.

Shannon Barber

Changing access protection of C++ members

Recommended Posts

IIRC, there''s a way in C++ to changing access privilege of inherited members (from public to protected for instance), but I can''t remember how to do it or what it''s technically called :/ Anyone know what I''m talking about?

Share this post


Link to post
Share on other sites
quote:
Original post by Magmai Kai Holmlor
IIRC, there''s a way in C++ to changing access privilege of inherited members (from public to protected for instance), but I can''t remember how to do it or what it''s technically called :/

Anyone know what I''m talking about?




Yeah, the using keyword. I use it a lot with private and protected inheritance:

class A
{
public:
void foo();
};

class B
: private A
{
public:
using A::foo;
};

Share this post


Link to post
Share on other sites
http://www.zib.de/benger/C%2B%2B/clause11.html#s11.3
http://www.zib.de/benger/C%2B%2B/clause7.html#s7.3.3

To change some members from public (in base) to protected (in derived), you''ll need to use protected inheritance and adjust the access of public members with the using declarations.

class Base {
public:
void foo() {}
void bar() {}
};

//for Derived, foo() is protected, bar() is public
class Derived : protected Base {
public:
using Base::bar;
};

Share this post


Link to post
Share on other sites
Yes, thanks, that''s what I thinking of (using).
Does it have a special name when you use it like that? As opposed to bringing a namespace into the local scope.

It look like you can inherit public and push things protected:

//A stack that doesn''t suck

template<typename T, class Alloc = std::allocator<T> >
struct Stack : std::deque<T, Alloc>
{
typedef std::deque<T, Alloc> container_t;
typedef typename std::deque<T, Alloc>::value_type value_type;
value_type& top();
const value_type& top() const;
void push(const value_type& _Val);
void pop();
protected:
using container_t::push_front;
using container_t::pop_front;
using container_t::push_back;;
using container_t::pop_back;
using container_t::insert;
};



error C2248: ''MKH::Util::Stack:ush_back'' : cannot access protected member declared in class ''MKH::Util::Stack''

Share this post


Link to post
Share on other sites
That's a using-declaration (C++ Std, 7.3.3 p115)...

And it looks like 7.3.3-15 p120 could be interpreted to allow what you're trying to do :
"The alias created by the using-declaration has the usual accessibility for a member declaration."

The mention of (deprecated) access-declarations (11.3 p178 - Hey, I didn't even know you could do that), seems to confirm it.

However, all the code examples seem to increase access rather than restrict it. Otherwise, since you're just hiding the base declaration with your own alias (hey, using references could work too), simply casting to the base type would provide access.


[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]


[edited by - Fruny on August 5, 2003 8:14:51 PM]

Share this post


Link to post
Share on other sites
VC7.1 tells me that friend is eschewed in favor of the newer using syntax, although I don''t quite see how. I guess just replace friend with using?

Share this post


Link to post
Share on other sites
quote:
Original post by Fruny
However, all the code examples seem to increase access rather than restrict it. Otherwise, since you're just hiding the base declaration with your own alias (hey, using references could work too), simply casting to the base type would provide access.



Using protected or private inheritance would restrict access (Added: Restricting access while using public inheritance would violate the "is-a" relationship.) and if I recall correctly you cannot cast to a base pointer for a protected or privately derived class (someone please correct me if I'm wrong...). So the using declaration can selectively reenable access to those members you still want public. It seems like you can get any desired level of access this way.



Edit: Aha! Found what I was looking for:

http://www.parashift.com/c++-faq-lite/private-inheritance.html#faq-24.4


[edited by - SpaceRogue on August 5, 2003 11:46:20 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by SpaceRogue
Using protected or private inheritance would restrict access (Added: Restricting access while using public inheritance would violate the "is-a" relationship.) and if I recall correctly you cannot cast to a base pointer for a protected or privately derived class (someone please correct me if I''m wrong...).



Well, if you have private inheritance, there is no need to further restrict member access - they''re all private, and if you have protected inheritance, derived classes can still cast back to their bases and access restrictions added through using-declarations can be bypassed.

Now, for the violation of the "is-a" relationship, the question is not whether it''s proper OOP, only if it is possible in C++.

See also Sutter''s "(Mostly) Private" July CUJ article for what it really means to be public, protected or private in C++.


[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]

Share this post


Link to post
Share on other sites