2

I'm wondering what kind of class member access friend functions and static member functions have for class objects. Specifically, what the differences are and why to use one over the other. It's my understanding that functions declared as friend of a class or as static members both have access to private members of any instance of that class.

I'll give a quick example to show why they seem so similar to me. Both functions operator< and MyClass::lessThan seem to have the same access privileges and can do the exact same thing.

class MyClass {
    friend bool operator<(const MyClass &left, const MyClass &right);
public:
    MyClass(int pub, int priv) : m_pub(pub), m_priv(priv) {}
    static bool lessThan(const MyClass &left, const MyClass &right);
    int m_pub;
private:
    int m_priv;
};

bool operator<(const MyClass &left, const MyClass &right) {
    return ( (left.m_pub < right.m_pub) && (left.m_priv < right.m_priv) );
}

bool MyClass::lessThan(const MyClass &left, const MyClass &right) {
    return ( (left.m_pub < right.m_pub) && (left.m_priv < right.m_priv) );
}

int main(int argc, const char* argv[]) {
    MyClass a(1, 2),
        b(3, 4),
        c(-1, 1);
    cout << "a < b        = " << (a<b) << endl;
    cout << "a lessThan b = " << MyClass::lessThan(a,b) << endl;
    cout << "a < c        = " << (a<c) << endl;
    cout << "a lessThan c = " << MyClass::lessThan(a,c) << endl;
}

Clearly this is a simplified example, but I suppose my question is two-part:

  1. What are the differences between friend and static functions in regards to member access?
  2. What kinds of things should come into consideration when deciding which to use?
Ayelix
  • 23
  • 4
  • 1
    The whole point of `friend` is to give other functions/classes private access. As for which to use, static functions can't access instance members. They're meant to be something you can call without an object. – chris Sep 12 '12 at 00:00
  • Also: `operator<(a, b)` compiles, while `lessThan(a, c)` doesn't. – Mooing Duck Sep 12 '12 at 00:09
  • chris - thanks, that's an important distinction I forgot about. However, what about situations like the example given here where the static function can access instance members because the instance is passed as an argument? – Ayelix Sep 12 '12 at 00:18
  • duck - the example here compiled for me, so I'm not sure what the problem would be. granted, I had some additional includes and such that are omitted here. – Ayelix Sep 12 '12 at 00:18
  • Unrelated to your actual question, but be aware that your `operator<` and `lessThan` are broken since they do not provide a strict weak ordering. :-] – ildjarn Sep 12 '12 at 00:44
  • @ildjarn - true, but this isn't real code (if you couldn't tell :P ). Also I noticed that my left and right operands were backwards so it was thoroughly broken. – Ayelix Sep 12 '12 at 01:06

5 Answers5

2

Remember that although prototypes for friend functions appear in a class definition, friend functions are not function members. A friend function of a class is defined away from the class, but a friend function has got access to non public members. Some people think "friendship" corrupts information hiding. Sometimes friend functions are used to make tester classes.

Static data members are used when an object class should to share an only one copy of a variable. So, you must use static data members for saving storage when just one copy is enough for all class members.

For static member functions you can look the following: When to use static member function?

Community
  • 1
  • 1
FacundoGFlores
  • 7,858
  • 12
  • 64
  • 94
  • friend definitely does not corrupt information hiding. It enhances it. It extends the interface of the class at the cost of tightly coupling the friend with the class http://programmers.stackexchange.com/q/99589/12917 This is better than tightly coupling all the code to your class. – Martin York Sep 12 '12 at 00:20
  • thank you, that result didn't come up in my search before posting. the "possible duplicate" linked from that question is especially helpful: [Where would you use a friend function vs a static function?](http://stackoverflow.com/questions/2315166/where-would-you-use-a-friend-function-vs-a-static-function) – Ayelix Sep 12 '12 at 00:26
1

They are different concepts:

If a class, method or function is friend of class X, that class, function or method has access to member of class X that were declared private and thus generally not accessible outside the class

class A{
  private:
     int x;
  friend void foo(A& a);

};

void foo(A& a){
    a.x = 3; //Access okay, foo is a friend of A
} 

void bar(A& a){
   a.x = -1; // Compiler will complain A::x is private
}

A static member is either a data member shared among all object instances of that class, or a method that can be called without a instance object of that class.

class B{

  private:
    static int y;

  public:
    static void printY();
    void alterY();

}

int B::y=3;

void B::printY(){
   cout<<y;
}

void B::alterY(){
   y++;
   cout<<y;
}


B b1,b2;
B::printY();// will output 3
b1.alterY();// will output 4
b2.alterY();// will output 5
André Oriani
  • 3,553
  • 22
  • 29
1

Static methods can be called without going through an instance of the class so they don't have any access directly, they are like global functions but nested in the class' namespace. However, if you give them an instance of that class as a parameter they will be able to access the member variables without going through accessors just like non static methods. Like static methods, friend functions if you give them an instance of the class they are friend of as a parameter they will be able to access member variables directly.

Borgleader
  • 15,826
  • 5
  • 46
  • 62
  • I guess I wasn't clear. What I meant to say is they can't access "their own" member variables because static methods are not called through an instance of the class. But yes if you give them an instance of that class as a parameter it'll work. – Borgleader Sep 12 '12 at 00:21
  • You make it sound like there is a difference between friend and static. There does not seem to be any. They both need to be passed a reference to an object before they can access any members. – Martin York Sep 12 '12 at 00:26
  • Now that you mention it my answer is a little misleading on that part. Will try to clear it up. – Borgleader Sep 12 '12 at 00:31
1
  1. They both have access to all members of the class, including the private ones
  2. You need to decide if a function logically belongs to the class the access to members of which it needs, or if it belongs to another class or no class at all. In the first case (a function that logically belongs to the class) make the function static; in the second case, make it a friend, and add to the class or the namespace where it logically belongs, according to your design.
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
0

What are the differences between friend and static functions in regards to member access?

None. They both a full access right.

What kinds of things should come into consideration when deciding which to use?

It completely depends on context and what makes the code easier to read.

In your example above I would definately prefer bool operator<() over MyClass::lessThan() as it makes the code more intuitive to read.

Martin York
  • 257,169
  • 86
  • 333
  • 562