Thread: Restricting Class

  1. #1
    Registered User
    Join Date
    Jan 2008
    Posts
    70

    Restricting Class

    I want to make a class that can only have its methods called by one other class.

    I am thinking right now that I should make everything private, and then make the other class a friend. I am not into the idea of letting the other class have access to my private data members however. If friendship is the only way to achieve this behavior, I think it is worth it however.

    I was wondering if anybody else has run into this issue, and what is the best way to approach it.

  2. #2
    Use this: dudeomanodude's Avatar
    Join Date
    Jan 2008
    Location
    Hampton, VA
    Posts
    391
    Several ways to go about methinks. Depends on the context of the problem though.

    You can have the "inner" class setup:
    Code:
    class foo{
      private:
        class bar{};
    };
    You can use inheritance:
    Code:
    class foo{
      protected:
        // members
    };
    
    class bar : public foo{};
    or go with friend

    EDIT: Only the "inner" (nested-clas) setup or friend route gurantee that only one class is even "aware" of the class in question.
    Ubuntu Desktop
    GCC/G++
    Geany (for quick projects)
    Anjuta (for larger things)

  3. #3
    Registered User
    Join Date
    Jan 2008
    Posts
    70
    Well I guess this is going to be my first foray into containing one class in another. It does look like that is the best way to do it, thanks.

  4. #4
    Use this: dudeomanodude's Avatar
    Join Date
    Jan 2008
    Location
    Hampton, VA
    Posts
    391
    Okay, it's worth noting on the inheritance however that we can restrict certain things that are inherited.

    Check this out:
    Code:
    class foo{
    
      private:
        // Won't be inherited
    
      public:
        // Of course it will be inherited
    
      protected:
        // basically private to everyone else except derived classes
    };
    So if you want your second class to only have "partial" functionality, you can split up the access this way. Perhaps this is better suited to your problem? I dunno. But as long as you don't have any other classes inherit from the first class, I don't see a problem...
    Ubuntu Desktop
    GCC/G++
    Geany (for quick projects)
    Anjuta (for larger things)

  5. #5
    Registered User
    Join Date
    Jan 2008
    Posts
    70
    It seems to me like the one class containing the other is the best. It's a FortressManager to Fortress relationship, I need all dealings with the Fortresses to go through the FortressManager or else bad things will happen.

  6. #6
    The larch
    Join Date
    May 2006
    Posts
    3,573
    It would seem strange though that you can talk to the FortressManager but for you there is no Fortress. But perhaps that is a naming issue?
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I don't think public inheritance is the key for this.
    You can use protected inheritance if you want to the class to be derivable, or private inheritance if you wish to disallow deriving.
    Public inheritance suggests an is a relationship.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Relationship is not the solution at all, since the two classes are not in a 1:1 relationship.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  9. #9
    Registered User
    Join Date
    Jan 2008
    Posts
    70
    It couldn't be done with inheritance, the FortressManager contains an array of Fortresses.

  10. #10
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by Drac View Post
    I want to make a class that can only have its methods called by one other class.
    The private inner class is one way to do that.
    Quote Originally Posted by Drac View Post
    I am thinking right now that I should make everything private, and then make the other class a friend. I am not into the idea of letting the other class have access to my private data members however.
    If class A trusts class B (and only class B) enough to allow calling of non-public member functions (that's what friendship means between C++ classes) why can't class B be trusted with other non-public attributes?

    As a rough rule, declaring friendship means that the programmer knows exactly what the friend class will do with its access.
    Quote Originally Posted by Drac View Post
    If friendship is the only way to achieve this behavior, I think it is worth it however.
    It's not the only way, but it is often the most logical way. There are various techniques, but you have to be specific in your goals (you have been specific in the form of solution you seek, which is not the same as being specific in your goals).

    I suggest you need to justify why you want to allow partial access.

    But to give you a hint, depending on what your goal is, alternatives include friendship, facade pattern, containment, a private inner class, and the pimple idiom.

  11. #11
    Registered User
    Join Date
    Jan 2008
    Posts
    70
    Quote Originally Posted by grumpy View Post
    you need to justify why you want to allow partial access.
    It's part of a game, I posted it in these forums because it seemed more like a broader issue. Fortress has methods such as addBuilding, which would make it seem like you could call this to add a building without any problems. Sadly if somebody did this they would be bypassing the collision detection that is done in FortressManager. I wrote this in the documentation, but I want a way to ensure that neither I or anyone else would access Fortress directly from anywhere except FortessManager.

    After this discussion the private inner class seem to me like the best and most explicit way to accomplish this.

  12. #12
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    The use of friend here, in my opinion, is a correct use. It is actually enhancing encapsulation and thus extending the protection. I have used this paradigm before and it works well. However it does not lend itself well to interfaces since friendship cannot be inherited. So you can't make the class a friend of the base and also of all it's derived. It is only a friend of the base and if the base is abstract then you have gained nothing. If you make the class a friend of the derived, it is only a friend of the derived you specified and not a friend of every derived that is derived from base.

    I have found the easiest way to enforce the idea that only certain objects can call functions in other objects is through friendship. Most people absolutely detest the use of friend but it does have it's legitimate uses and trying every other construct just to keep yourself from using friend may result in a more complex system that is overdesigned for the task.

    You can also affect 'visibility' of functions through interfaces but it can get complex fairly quickly. You would return a pointer to an interface that did not support the functionality you are wanting to hide but did support all of the functionality that every object can access. To the one object that can indeed use the 'hidden or forbidden' functionality you would return the interface that supported those functions. In this way you would limit which objects could access specific functions in another object. I believe this would fall under the aforementioned 'facade' pattern.

    Inherited friendship would be a very nice addition to the language since you could then say that since class A is a friend of Base and Derived is derived from Base then A is also a friend of Derived. As it stand now A is only a friend of either Base or Derived but never both unless friend is both declared in Base and Derived...in which case the declaration in Base is a moot point.
    Last edited by VirtualAce; 12-08-2008 at 06:18 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Class design problem
    By h3ro in forum C++ Programming
    Replies: 10
    Last Post: 12-19-2008, 09:10 AM
  2. Defining derivated class problem
    By mikahell in forum C++ Programming
    Replies: 9
    Last Post: 08-22-2007, 02:46 PM
  3. matrix class
    By shuo in forum C++ Programming
    Replies: 2
    Last Post: 07-13-2007, 01:03 AM
  4. Replies: 7
    Last Post: 05-26-2005, 10:48 AM