What kind of member access do friend and static me

2019-07-09 00:47发布

问题:

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?

回答1:

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?



回答2:

  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.


回答3:

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


回答4:

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.



回答5:

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.