开发者

Keeping part of public nested class visible only to the nesting class

I have a nested class in c++ which has to be public. But I need some of its methods visible to the outer world, and the rest visible only to the nesting class. That is:

class set {
public:
    class iterator {
开发者_开发百科        innerMethod();
    public:
        outerMethod();
    }
}

I want to be able to write a method for set which uses innerMethod(). If I make it public, I can access it from outside as well, which is something that I definitely don't want. Is there a way to do it without doing the "friend class set" thing?

Thanks in advance!


There is NO GOOD WAY you can do this, without using friend keyword.

In the comment you said:

In the programming class I currently take, using 'friend' was said to be ill-advised and generally considered "bad programming" for the most part, unless there is really no other way around it. So I try to avoid it as much as possible.

friend breaks encapsulation, maybe that is the reason why your class teacher said it's bad-programming. But member-functions too break encapsulation, then why do you use them? Why not avoid them too? friend breaks encapsulation in the same way as do member-functions; so if you're comfortable using member-functions when they're needed, then you should be comfortable using friend also when they're needed. Both exist in C++ for a reason!

class set {
public:
 class iterator 
 {
  friend class set; //<---- this gives your class set to access to inner methods!

  void innerMethod(){}
 public:
  void outerMethod(){}
 };
 iterator it;

 void fun()
 {
  it.innerMethod();
  it.outerMethod();
 }
};

See this : How Non-Member Functions Improve Encapsulation


No, I don't think there are other non-hacky methods but using the friend-directive.

friend exists right for this kind of purpose, why would you avoid it?


Try asking: is there any way to add 2 numbers without adding them? Sorry if I'm harsh, but friend class is for exactly that...


Yes there is.

I've been trying to advocate the method for a while now, the basic idea is to use a Key class.

While this does not actually remove the use of friend, it does reduce the set of exposed implementations details.

class set;

// 1. Define the Key class
class set_key: noncopyable { friend class set; set_key() {} ~set_key() {} };

class set
{

  // 2. Define the iterator
  class iterator
  {
  public:
    void public_method();

    void restricted_method(set_key&);

  }; // class iterator

}; // class set

Now, restricted_method is public, so set does not need any special access to iterator. However the use of it is restricted to those able to pass a set_key instance... and conveniently only set may build such an object.

Note that set may actually pass a set_key object to someone else it trusts. It is a key in the traditional sense: if you give a key of your flat to someone, it may entrust it to another person. However because of the semantics of the key class (non copyable, only set may construct and destroy it) this is normally limited to the duration of the scope of the key object.

Note that a evil hack is always possible, namely *((set_key*)0). This scheme protects from Murphy, not Machiavelli (it's impossible in C++ anyway).


You can do something like this:

class set

{

public:
    class iterator
    {
        protected:
            iterator(){};
            virtual ~iterator(){};

        public:
            //outer world methods...
    };

private:
    class privateIterator : public iterator
    {
        public:
            privateIterator(){};
            ~privateIterator(){}

        //inner methods;
    };

public:
    iterator* CreateIterator()
    {
        return new privateIterator();//this is used to be sure that you only create private iterator instances
    }

};

I don't know if it's the right answer, but it does now uses friend key work and it hides some of the methods. The only problem is that you can't declare privateIterator and you always must use CreateIterator to create an instance...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜