Where would you use a friend function vs. a static member function?
Asked Answered
O

15

85

We make a non-member function a friend of a class when we want it to access that class's private members. This gives it the same access rights as a static member function would have. Both alternatives would give you a function that is not associated with any instance of that class.

When must we use a friend function? When must we use a static function? If both are viable options to solve a problem, how do we weigh up their suitability? Is there one that should be preferred by default?

For example, when implementing a factory that creates instances of class foo which only has a private constructor, should that factory function be a static member of foo (you would call foo::create()) or should it be a friend function (you would call create_foo())?

Othelia answered 22/2, 2010 at 23:46 Comment(20)
The property of being a "friend" and the property of being "static" are orthogonal. There's no interchangeability between them, which makes your question sound like "Where would you use a car instead of a microscope?". Could you, please, clarify, what exactly i simplied by the question? Why are you asking it? Otherwise, it is difficult to even begin figuring out which end to approach it from.Brahmi
If you overload an operator, it could be done via both, so which is better?Othelia
um, they are very closely related and there is hardly any difference between themLonger
@AndreyT and perhaps others - I've wondered this question myself. The two concepts are not entirely orthogonal because static member functions have access to private members of any object of their class, in the same way a friend function does.Donley
@Swapna: Incorrect. In C++ language you cannot use static member functions for operator overloading. The language specification explicitly states in 13.5/6: "An operator function shall either be a non-static member function or be a non-member function". So, what kind of "static" are you talking about? Static as in "static member"? Or static as in "internal linkage"?Brahmi
Try these links from the C++ FAQ Lite: parashift.com/c++-faq-lite/friends.html#faq-14.3, and parashift.com/c++-faq-lite/input-output.html#faq-15.8Egor
@Andrey, so guess, that answers my question as to where friend functions are used! Will try if this rule is enforced by the gcc.Othelia
the only difference between static function and friend function is that the static function is in the scope of the class but the friend is not. see stroustrup 11.5Longer
@pm100: wrong (even if dated), a friend function may be friend with multiple different classes at once. A static can obviously pertain to a single class... though it could be friend with the others of course :)And
A static member function and an external friend function both have access to private members of the class. So he might be asking why you would use one rather than the other. Operator overloading is an instance you can only use friend.Glynda
@AndreyT: if friend and static were orthogonal concepts then they could be used independently, the fact is that a function cannot be a friend and static at the same time; therefore they are not orthogonal.Bertrambertrand
@alfC: I'm not sure what you are saying here. Firstly, static and friend can be used independently. Secondly, a function can be friend and static at the same time.Brahmi
@AndreyT: We are talking about a static-member-function here. and no, a static-member-function cannot be friend also. Just try to compile this struct A{friend void afriend(){} static void astatic(){} friend static void astaticfriend(){}};. That's why I think pm100's answer is the one that makes most sense. Am I missing something?Bertrambertrand
@alfC: You are insisting on a specific example where the function is static and friend in the same class. Why? I can make an example when a static member function of class A is a friend of class B. Why aren't you considering such examples as well?Brahmi
@AndreyT: I see your point now. However the example involving only one class is, I think, the only context in which the question makes sense, specially because the use of the "vs." word in question. Otherwise there is no question at all, whether friend needs to be used.Bertrambertrand
To achieve what??? That's not a real question by means of technical issues, since these are really orthogonal. Further I think using friend might not be a good design idea except for rare cases. Generally you should consider a concept of protected/internal interfaces instead.Blackett
@g-makulik I think the question is really asking about friend non-member functions vs. static member functions, in which case I'd say they weren't really orthogonal.Ironmaster
@sftrabbit But I'd suspect friend to be a primary choice design element anyway. And additionally the question should elaborate your point more clearly (what about editing it?) ...Blackett
@g-makulik Fair point. I've fleshed out the question.Ironmaster
@JosephMansfield fleshed out -- thank you for that :) Unfortunately SO has not yet allowed to reward such altruistic actions.Epineurium
L
86

Section 11.5 "The C++ Programming Language" by Bjarne Stroustrup states that ordinary member functions get 3 things:

  1. access to internals of class
  2. are in the scope of the class
  3. must be invoked on an instance

friends get only 1.

static functions get 1 and 2.

Longer answered 23/2, 2010 at 0:8 Comment(5)
best answer IMO, despite the historical different uses, friend is more general than static(-member functions) since it can do the same job but their namespace scope is more flexible. A minor point is that friend functions cannot be called with a class instance, (e.g. A a; a.static_member(); but the usage is not very common)Bertrambertrand
When is being in the same scope of the class beneficial or not?Ironmaster
@sftrabbit you should post that as a question. The answer could be long and outside of the scope of this answer.Rabblerousing
Are you sure that reference is correct? Section 11.5 of 'The C++ Programming Language' by Bjarne Stroustrup is about "Explicit Type Conversion" and does not appear to make mention of the difference between static and friend functions.Corgi
You're just making a list of the possible benefits whilst the OP's asking why and where you would prefer those benefits over the other's. Sorry for bringing it up again.Archimandrite
W
58

The question seems to address the situation where the programmer needs to introduce a function that does not work on any instance of a class (hence the possibility of choosing a static member function). Therefore, I will limit this answer to the following design situation, where the choice is between a static function f() and a friend free function f():

struct A
{
    static void f();     // Better this...
private:
    friend void f();  // ...or this?
    static int x;
};

int A::x = 0;

void A::f() // Defines static function
{
    cout << x;
}

void f() // Defines friend free function
{
    cout << A::x;
}

int main()
{
    A::f(); // Invokes static function
    f();    // Invokes friend free function
}

Without knowing anything in advance about the semantics of f() and A (I'll come back to this later), this limited scenario has an easy answer: the static function is preferable. I see two reasons for this.


GENERIC ALGORITHMS:

The main reason is that a template such as the following can be written:

template<typename T> void g() { T::f(); }

If we had two or more classes that have a static function f() on their interface, this would allow us writing one single function that invokes f() generically on any such class.

There is no way to write an equivalent generic function if we make f() a free, non-member function. Although it is true that we could put f() into a namespace, so that the N::f() syntax could be used to mimic the A::f() syntax, it would still be impossible to write a template function such as g<>() above, because namespace names are not valid template arguments.

REDUNDANT DECLARATIONS:

The second reason is that if we were to put the free function f() in a namespace, we would not be allowed to inline its definition directly in the class definition without introducing any other declaration for f():

struct A
{
    static void f() { cout << x; } // OK
private:
    friend void N::f() { cout << x; } // ERROR 
    static int x;
};

In order to fix the above, we would to preceed the definition of class A with the following declaration:

namespace N
{
    void f(); // Declaration of f() inside namespace N
}

struct A
{
    ...
private:
    friend void N::f() { cout << x; } // OK
    ...
};

This, however, defeats our intention of having f() declared and defined in just one place.

Moreover, if we wanted to declare and define f() separately while keeping f() in a namespace, we would still have to introduce a declaration for f() before the class definition for A: failing to do so would cause the compiler to complain about the fact that f() had to be declared inside namespace N before the name N::f could be used legally.

Thus, we would now have f() mentioned in three separate places rather than just two (declaration and definition):

  • The declaration inside namespace N before A's definition;
  • The friend declaration inside A's definition;
  • The definition of f() inside namespace N.

The reason why the declaration and definition of f() inside N cannot be joined (in general) is that f() is supposed to access the internals of A and, therefore, A's definition must be seen when f() is defined. Yet, as previously said, f()'s declaration inside N must be seen before the corresponding friend declaration inside of A is made. This effectively forces us to split the declaration and the definition of f().


SEMANTIC CONSIDERATIONS:

While the above two points are universally valid, there are reasons why one might prefer declaring f() as static over making it a friend of A or vice versa which are driven by the universe of discourse.

To clarify, it is important to stress the fact that a member function of a class, whether it is static or non-static, is logically part of that class. It contributes to its definition and thus provides a conceptual characterization of it.

On the other hand, a friend function, in spite of being granted access to the internal members of the class it is friend of, is still an algorithm which is logically external to the definition of the class.

A function can be friend of more than one class, but it can be member of just one.

Thus, in a particular application domain, the designer may want to keep into consideration the semantics of both the function and the class when deciding whether to make the former a friend or a member of the latter (this applies not only to static functions, but to non-static functions as well, where other language constraints may intervene).

Does the function logically contribute to characterize a class and/or its behavior, or is it rather an external algorithm? This question can't be answered without knowledge of the particular application domain.


TASTE:

I believe that any argument other the ones just given stems purely from a matter of taste: both the free friend and the static member approach, in fact, allow to clearly state what the interface of a class is into one single spot (the class's definition), so design-wise they are equivalent (modulo the above observations, of course).

The remaining differences are stylistic: whether we want to write the static keyword or the friend keyword when declaring a function, and whether we want to write the A:: class scope qualifier when defining the class rather than the N:: namespace scope qualifier. Thus, I will not comment further on this.

Wotan answered 14/2, 2013 at 14:5 Comment(2)
Great answer. This is the kind of thing I was looking for.Ironmaster
@AndyProwl What about to combine in one namespace - class and friend functions? Friend fuctions are non-members then they give better encapsulation than static member functions. Scott Meyers recommends non-member functions in Item 23. And here: cpptips.com/nmemfunc_encapRenewal
C
13

The difference is clearly expressing the intent of the relationship between the class and the function.

You use friend when you want to intentionally indicate a strong coupling and special relationship between two unrelated classes or between a class and a function.

You use static member function when the function is logically a part of the class to which it is a member.

Cresida answered 11/2, 2013 at 15:11 Comment(0)
T
7

Friend functions (and classes) can access the private and protected members of your class. There's rarely a good case for using a friend function or class. Avoid them in general.

Static functions may only access static data (that is, class-scoped data). They may be called without creating an instance of your class. Static functions are great for circumstances you want all of the instances of your class to behave the same way. You can use them:

  • as callback functions
  • to manipulate class-scoped members
  • to retrieve constant data that you don't want to enumerate in your header file
  • Termor answered 23/2, 2010 at 0:3 Comment(3)
    ^^This, i cam glad someone posted that they generally should be avoided !Carollcarolle
    this answer is slightly misleading. Static function can access class private data; but they have to have some way to reach the instance (ie an instance is passed to the static function). A common example is a factory method that creates an object then fiddles with its internal before returning it to the callerLonger
    It is not misleading. A static function cannot access instance data. What it can do is access instance data via an instance, but not directly.Flinn
    V
    6

    Static functions are used when you want a function that is the same for every instance of a class. Such functions do not have access to "this" pointer and thus cannot access any non static fields. They are used often when you want a function that can be used without instantiating the class.

    Friend functions are functions which are not in the class and you want to give them access to private members of your class.

    And this(static vs. friend) is not a matter of using one vs the other since they are not opposites.

    Ventilation answered 22/2, 2010 at 23:55 Comment(4)
    If you use a static function before instantiation, why associate it with the class? Could you give an example? Trying to get my head around this... Thanks!Othelia
    Lets say you have a class named Converter and all it does it converts units. You could have static functions such as Converter.ConvertFromMetersToMiles() , its logical to have those functions but you have no need to instantiate the class.Ventilation
    Your other functions can access your static data, so you could use a static function to set a static variable that controls some behavior of all of the instances of your class. There are obvious thread safety considerations in this kind of example, though.Termor
    So you've described that a static function is a member function that has been disassociated from any particular object and a friend function is a non-member function that has been given access rights to a class. So they're the same thing? When should one be used over the other?Ironmaster
    F
    2

    The standard requires that operator = () [] and -> must be members, and class-specific
    operators new, new[], delete and delete[] must be static members. If the situation
    arises where we don't need the object of the class to invoke a function, then make
    the function static. For all other functions:
    if a function requires the operators = () [] and -> for stream I/O,
    or if it needs type conversions on its leftmost argument, or if it can be implemented using the class' public interface alone, make it nonmember ( and friend if needed in the first two cases)
    if it needs to behave virtually,
    add a virtual member function to provide the virtual behaviour
    and implement in terms of that
    else
    make it a member.

    Fremont answered 23/2, 2010 at 0:9 Comment(0)
    M
    2

    Static function can only access members of one class. Friend function has access to several classes, as explained by the following code:

    class B;
    class A { int a; friend void f(A &a, B &b); };
    class B { int b; friend void f(A &a, B &b); };
    void f(A &a, B &b) { std::cout << a.a << b.b; }
    

    f() can access data of both A and B class.

    Methacrylate answered 9/2, 2013 at 20:26 Comment(0)
    T
    2
    • One reason to prefer a friend over static member is when the function needs to be written in assembly (or some other language).

      For instance, we can always have an extern "C" friend function declared in our .cpp file

      class Thread;
      extern "C" int ContextSwitch(Thread & a, Thread & b);
      
      class Thread
      {
      public:
          friend int ContextSwitch(Thread & a, Thread & b);
          static int StContextSwitch(Thread & a, Thread & b);
      };
      

      And later defined in assembly:

                      .global ContextSwitch
      
      ContextSwitch:  // ...
                      retq
      

      Technically speaking, we could use a static member function to do this, but defining it in assembly won't be easy due to name mangling (http://en.wikipedia.org/wiki/Name_mangling)

    • Another situation is when you need to overload operators. Overloading operators can be done only through friends or non-static members. If the first argument of the operator is not an instance of the same class, then non-static member would also not work; friend would be the only option:

      class Matrix
      {
          friend Matrix operator * (double scaleFactor, Matrix & m);
          // We can't use static member or non-static member to do this
      };
      
    Tibold answered 11/2, 2013 at 15:2 Comment(0)
    G
    1

    A static function is a function that does not have access to this.

    A friend function is a function that can access private members of the class.

    Gladiatorial answered 22/2, 2010 at 23:54 Comment(1)
    a static function has access to the internals of the class tooLonger
    H
    1

    You would use a static function if the function has no need to read or modify the state of a specific instance of the class (meaning you don't need to modify the object in memory), or if you need to use a function pointer to a member function of a class. In this second instance, if you need to modify the state of the resident object, you would need to pass this in and use the local copy. In the first instance, such a situation may happen where the logic to perform a certain task is not reliant on an object's state, yet your logical grouping and encapsulation would have it be a member of a specific class.

    You use a friend function or class when you have created code that is not a member of your class and should not be a member of your class, yet has a legitimate purpose for circumventing the private/protected encapsulation mechanisms. One purpose of this may be that you have two classes that have need of some common data yet to code the logic twice would be bad. Really, I have only used this functionality in maybe 1% of the classes I've ever coded. It is rarely needed.

    Harry answered 22/2, 2010 at 23:59 Comment(0)
    C
    1

    A friend function can not be inherited while a static function can be. So when an aim can be achieved with both static function and friend function, think that whether you want to inherit it or not.

    Cotten answered 17/10, 2016 at 12:52 Comment(0)
    B
    0

    Static function can be used in many different ways.

    For example as simple factory function:

      class Abstract {
      private:
        // no explicit construction allowed
        Abstract(); 
        ~Abstract();
    
       public:
         static Abstract* Construct() { return new Abstract; }
         static void Destroy(Abstract* a) { delete a; }
       };
    
       ...
       A* a_instance = A::Conctruct();
       ...
       A::Destroy(a_instance);
    

    This is very simplified example but I hope it explains what I meant.

    Or as thread function working with Your class:

     class A {
    
     public:
        static void worker(void* p) {
                A* a = dynamic_cast<A*>(p);
                do something wit a;
        }   
     } 
    
     A a_instance;
     pthread_start(&thread_id, &A::worker, &a_instance);
     .... 
    

    Friend is completely different story and they usage is exactly as described by thebretness

    Belford answered 23/2, 2010 at 0:8 Comment(0)
    B
    0

    Friend functions can access the private and protected members of other classes. Means they can be used to access all the data weather it is private or public. So friend functions are used to access that data which static methods can not.

    Those methods are made static which are called so many times that declaring a different location inside every object, for them becomes too costly(In terms of memory). This can be made clear with the help of example: Let the class's name is fact and its data member is n(which represents integer whose factorial is concern) then in this case declaring find_factorial() as static would be wise decision!!

    They are used as callback functions to manipulate class-scoped members to retrieve constant data that you don't want to enumerate in your header file

    Now we are clear with following questions..

    When a friend function is used? When a static function is used?

    Now If both are viable options to solve a problem, We can weight up their suitability in terms of accessibility(accessibility of Private data) and memory efficiency. By default no one can be preferred as there are many situation when we need better memory management and sometimes we are are concerned with the scope of data.

    For example: foo::create() will be preferred over create_foo() when we have to call create() method after every small instance of time and we are not interested on scope of data(Private data)

    And if we are interested to get the private information of more than one class(s) then create_foo() will be preferred over foo::create().

    I hope this would help you!!

    Blandishments answered 14/2, 2013 at 23:31 Comment(0)
    O
    -1

    Here is what I think it is:

    Friend function- when you need access to a different class member, but the classes are not related. Static function- when you no not need access to the 'this' pointer. But, I have a feeling there is more to it....

    Othelia answered 22/2, 2010 at 23:55 Comment(1)
    Well, (your(?)) good question collected a lot of insightful answers. I'd suggest to delete this - in my opinion hopeless - "competitor".Epineurium
    D
    -2
    1. Static data members always share the memory.
    2. only static function can used static data members.
    3. static member function can be called with class name.
    4. They must be defined outside of the class when we create a object of static member or member function in the class. It will automatically initialize the value.
    5. It always used keyword static.
    6. Static members can share by all the objects.
    7. Type and scope of data members and member function is outside of the class.
    8. A static member variable must be defined outside of the class.
    Debunk answered 12/10, 2016 at 1:41 Comment(1)
    #2 isn't even true, and all the rest seem to be about static data members while the question is about member functions.Thebes

    © 2022 - 2024 — McMap. All rights reserved.