From: AK on
Hi,

Is there a C++ approach to deriving a class such that only a subset of
the base class' public member functions are available to it?
For a concrete example: I may wish to use STL's linked list class to
create a new "specialized" linked list class in which nodes can only
be added to the list according to some specified ordering rule (say
defined by '<', appropriately defined for the node type), so I don't
want to provide the user of my specialized linked list to be able to
use the push_back() and push_front() methods from STL's linked list.
Do I need to override these functions so that they don't do anything
in my derived class, or is there a better way?

Any help and/or pointers to appropriate reading material would be
appreciated!

AK

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Sean Hunt on
On Apr 6, 6:23 pm, AK <danr...(a)gmail.com> wrote:
> Hi,
>
> Is there a C++ approach to deriving a class such that only a subset of
> the base class' public member functions are available to it?
> For a concrete example: I may wish to use STL's linked list class to
> create a new "specialized" linked list class in which nodes can only
> be added to the list according to some specified ordering rule (say
> defined by '<', appropriately defined for the node type), so I don't
> want to provide the user of my specialized linked list to be able to
> use the push_back() and push_front() methods from STL's linked list.
> Do I need to override these functions so that they don't do anything
> in my derived class, or is there a better way?

Private inheritance is the best way to do this. Then, in the text of
the class, you can write "using base::function" to import each
function you want (and all overloads). You can't do this for
constructors though. Private inheritance also neatly avoids the
virtual destructor problem, because you will never have a user upcast
a pointer/reference.

> Any help and/or pointers to appropriate reading material would be
> appreciated!
>
> AK

Hmm... this isn't in the FAQ Lite. It should be. Where can I tell the
guy that there needs to be something on this subject?

Sean Hunt

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Carl Barron on
AK <danrop1(a)gmail.com> wrote:

> Hi,
>
> Is there a C++ approach to deriving a class such that only a subset of
> the base class' public member functions are available to it?
> For a concrete example: I may wish to use STL's linked list class to
> create a new "specialized" linked list class in which nodes can only
> be added to the list according to some specified ordering rule (say
> defined by '<', appropriately defined for the node type), so I don't
> want to provide the user of my specialized linked list to be able to
> use the push_back() and push_front() methods from STL's linked list.
> Do I need to override these functions so that they don't do anything
> in my derived class, or is there a better way?
>
> Any help and/or pointers to appropriate reading material would be
> appreciated!
>
> AK

1) you can use containment that is your_list has an std::list<...> data
member amd only provides access to it via your member functions.

2) private inheritance and using declarations of the part you want the
user to see.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Gerhard Menzl on
> Is there a C++ approach to deriving a class such that only a subset of
> the base class' public member functions are available to it?
> For a concrete example: I may wish to use STL's linked list class to
> create a new "specialized" linked list class in which nodes can only
> be added to the list according to some specified ordering rule (say
> defined by '<', appropriately defined for the node type), so I don't
> want to provide the user of my specialized linked list to be able to
> use the push_back() and push_front() methods from STL's linked list.
> Do I need to override these functions so that they don't do anything
> in my derived class, or is there a better way?
>
> Any help and/or pointers to appropriate reading material would be
> appreciated!

Public inheritance would be the wrong design choice in this case.
Restricting the interface of a base class is a violation of the Liskov
Substitution principle. In addition, std::list has not been designed to
be used as a public base class.

Public inheritance models IS-A or BEHAVES-LIKE-A. As you say yourself,
the relationship between your class and std::list is USES. There are two
basic options to implement this type of relationship: use private
derivation and pull in the subset of the interface you want to support
via using, or make a std::list a member of your class and provide
suitable wrapper functions. The former approach incurs less initial
effort, but the latter solution is more flexible and reduces coupling.
For example, it is much easier to replace std::list by something else if
it is used as a member rather than as a private base class.

For reading, I strongly recommend Herb Sutter's "Exceptional C++", Items
22 to 24.

--
Gerhard Menzl

Non-spammers may respond to my email address, which is composed of my
full name, separated by a dot, followed by at, followed by "fwz",
followed by a dot, followed by "aero".


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Ulrich Eckhardt on
AK wrote:
> Is there a C++ approach to deriving a class such that only a subset of
> the base class' public member functions are available to it?

Yes, refactor your design so that this is not necessary. The typical example
where things like you request are done is in some widget sets where the
baseclass contains all functions possible and the derived classes implement
those that make sense to them and leave the others as stubs.

> For a concrete example: I may wish to use STL's linked list class to
> create a new "specialized" linked list class in which nodes can only
> be added to the list according to some specified ordering rule (say
> defined by '<', appropriately defined for the node type), so I don't
> want to provide the user of my specialized linked list to be able to
> use the push_back() and push_front() methods from STL's linked list.
> Do I need to override these functions so that they don't do anything
> in my derived class, or is there a better way?

This is a slightly different thing. What I guess you actually want is a
special container. For that, it is useful to base your work on existing
container types, but that should be an implementation detail. In
particular, you should not derive your container publicly from std::list,
but rather derive privately or use aggregation. In any case, if the user
gets hold of the std::list part of your class, they can also use push_front
on it, you can not change that. What you can change is access to the
std::list, i.e. you wrap it in your code. In that case, private derivation
comes handy, because for the 'safe' parts you can then simply forward them
with 'using baseclass::begin;' because this function can't change the
required order.

In any way, the OOP approach using derivation is not applicable, because
std::list has no virtual functions that you could customise. Rather, you
will have to use containment, private derivation being just a C++-specific
way of containment.

Uli

--
Sator Laser GmbH
Geschäftsführer: Michael Wöhrmann, Amtsgericht Hamburg HR B62 932


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

 |  Next  |  Last
Pages: 1 2 3 4
Prev: Composition
Next: unordered_map