|
Prev: Composition
Next: unordered_map
From: AK on 6 Apr 2008 09:23 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 7 Apr 2008 01:13 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 7 Apr 2008 01:13 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 7 Apr 2008 01:43 > 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 7 Apr 2008 01:43
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! ] |