1

I know friend classes and I want exactly opposite of it.

Ex: Class A has a public function named F. While other 30 classes have access to F function, Class Z cannot access to F function.

Erkam D
  • 49
  • 6
  • 3
    What about children of Z and the classes of the objects it creates? Can those access F? What's preventing Z from simply constructing a proxy to access F? This seems like it might be an XY problem. – jaggedSpire Jul 13 '16 at 17:00
  • If some classes shouldn't have access to a function, it should be protected/private, and it should `friend` the classes that need access. That's what the feature exists for. – Mooing Duck Jul 13 '16 at 17:09
  • @MooingDuck There actually are ways to refactor the `friend` relationship. Have a look at my (linked) answer. – πάντα ῥεῖ Jul 13 '16 at 17:14
  • @jaggedSpire Derived classes of Z is not so important for my case. Why do I want to construct proxy access to F function, I want to prevent accessing F function from Z class. – Erkam D Jul 19 '16 at 12:48
  • @wArtist my point is even if there was a simple, elegant way to prevent access from a *single* class, it would be incredibly easy to circumvent and therefore offer no reliable guarantees regarding access protection within the class. Preventing access to a single class would be a show more than anything else--it wouldn't prevent anything from getting called in `Z`'s member functions. If you want to prevent access to some subset of public functions, make an accessing wrapper class that only provides access to the relevant functions, and pass *that* in to the revelvant function instead. – jaggedSpire Jul 19 '16 at 14:11
  • @jaggedSprite Hmm, I think I have forgotten to say that the 30 classes already have numerous calls on F function. I don't want to change codes in them. I simply want to prevent access of Z class on funtion F without changing other classes' way of call F function. – Erkam D Jul 29 '16 at 15:26

3 Answers3

4

If the function is public you cannot prevent others from calling it.

You can make it so that the function is not exported by the linker outside the library where it is implemented, but that's about it.

What problem are you actually trying to solve?

Jesper Juhl
  • 30,449
  • 3
  • 47
  • 70
  • Problem is as I said, function must be public because it is being using from many other classes. Making these classes friend is long story. So I want a shortcut to the problem. – Erkam D Jul 13 '16 at 21:27
1

As mentioned in the other answers, there's no way to kind of unfriend or exclude a particular class from your public interface.


Though you can use the same principle I to have protected interfaces, as have described in this Q&A:

How can I remove/refactor a «friend» dependency declaration properly?.

This would require a client to implement a specific interface to call a function from the class that provides the protected interface:

Here's the C++ implementation:

class ClassAAccessor {
public:
    ClassAAccessor(ClassA& classA);
    void setInternalInterfaceRef(InternalInterface & newValue) {
        internalInterfaceRef = &newValue;
    }
private:  
    InternalInterface* internalInterfaceRef;
};

This one is actually called, when the also newly introduced method ClassA::attachAccessor() method is called:

class ClassA : protected InternalInterface {
public:
    // ...
    attachAccessor(ClassAAccessor & accessor);
    // ...
};

ClassA::attachAccessor(ClassAAccessor & accessor) {
    accessor.setInternalInterfaceRef(*this); // The internal interface can be handed
                                             // out here only, since it's inherited 
                                             // in the protected scope.
}

Thus the constructor of ClassAAccessor can be rewritten in the following way:

ClassAAccessor::ClassAAccessor(ClassA& classA)
: internalInterfaceRef(0) {
    classA.attachAccessor(*this);
}

I don't want to mark your question as duplicate, because the answer I link was more about UML design, but contains a c++ sample.

Community
  • 1
  • 1
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
0

Off the top of my head, I don't think that's possible. You want Z calls to A::F to generate a compile error? I'm not sure how you would even add that feature to a language. If such a feature did exist, then either you would have to create a list in Class A which contains all of the targets which can or cannot use function F, or you would need to specify in other classes that they are not allowing themselves to use A::F.

So you want something like

class Z {
    denied A::F;
}

That would probably be the best/easiest way to add such a feature, with some keyword meant to be used like above.

I don't think it exists. Features like friend exist because it is often very useful to add accessibility to something which normally you could not access. It is rarely necessary to specifically remove accessibility to something you normally can access, and the answer from compiler engineers would probably be "Just don't use A::F in Z."

Not saying the idea is dumb or that it's useless, just that it's not useful enough to be a feature, which is why I don't think it is one.

Loduwijk
  • 1,950
  • 1
  • 16
  • 28
  • If panta's (sorry, poor Greek support on this system) answer is getting at what you want, then I must be misunderstanding what you want. We could use some clarification about which route you are looking for. – Loduwijk Jul 13 '16 at 17:10