1

I have a class (say MyClass) and functions that take instances of MyClass as arguments. The functions need to access private members of MyClass. The members are private because users of MyClass don't need to be know about the members. However, I don't want to make the functions members of MyClass because the functions should take several MyClass instances as arguments and the arguements are treated symmetrically. I don't want to deal "this" object specially.

If there were a kind of module system so I could declare a module containing the functions as a friend of MyClass, I would be happy. But there is no such things in C++. One way is to make a friend class and make the functions static members of the class. However, many people don't recommend the way (eg. Namespace + functions versus static methods on a class) because class is not intended for such use.

Any design solution for this case?

Community
  • 1
  • 1
strugi
  • 169
  • 1
  • 1
  • 5

3 Answers3

2

namespace is the currently relevant feature. But isn't possible to get a friend namespace, no more that it is possible to template a namespace or pass a namespace as a template parameters, two common cases where struct with only static members are commonly used as a work around. So there is a good precedent of using a struct. There is at least another reason to use a struct of static members instead of a namespace: a namespace is open to addition while a struct is closed. And that aspect alone could be also a justification of using a struct instead of a namespace for friend.

AProgrammer
  • 51,233
  • 8
  • 91
  • 143
0

Friends do not have to be classes. You can declare a function to be a friend.

David K
  • 3,147
  • 2
  • 13
  • 19
  • 3
    Yes, I know. However, declaring 17 functions (and the number may increase) as friends seems not a beautiful solution. – strugi Oct 09 '14 at 15:13
  • @strugi Do you really have 17 different things whose only commonality is that they all take one or more instances of `MyClass` as input? If so, and if none of them can make do with the public interface that `MyClass` should present anyway, then I think the 17 friend functions is the logical result of your design and it makes sense (within that constraint) to declare them. (With or without friend declarations, I find the idea of those 17 functions a bit disturbing.) – David K Oct 09 '14 at 23:01
0

You typically implement such functions as free-standing functions which are members of the target class. You can implement them "literally" inside the class but still they are free-standing. So you don't need to repeat yourself when listing all those functions as friends + implement them:

class MyClass {
    int x;

    friend void doSomething(MyClass & obj) {
        obj.x++;
    }
    friend bool doSomethingDifferent(MyClass & a, MyClass & b) {
        return a.x < b.x;
    }
};
leemes
  • 44,967
  • 21
  • 135
  • 183
  • Wow! I did'n know such syntax exists. Thank you very much! – strugi Oct 09 '14 at 15:19
  • 1
    I did some experiments with that. It seems that I have to put separate declarations of the functions. If I don't, only argument dependent lookup can call the functions. (http://stackoverflow.com/questions/8207633/whats-the-scope-of-inline-friend-functions). – strugi Oct 09 '14 at 16:29
  • Okay, I didn't know about the namespace problems. But isn't ADL just fine in your case? I mean, you're going to call it with some `MyClass` object as an argument, so ADL should work perfectly... When does it fail? – leemes Oct 09 '14 at 21:27